React MSAL Library msal-react : Issue in logging out in B2C application - azure

I am using msal-react in my single page B2C application to sign in. I used the loginRedirect() function to login.
const { instance } = useMsal();
let {idToken} = await instance.loginRedirect();
This is allowing me to login successfully.
After login when I check if the user is authenticated using the following function it is returning true.
import {useIsAuthenticated,} from "#azure/msal-react";
const isAuthenticated = useIsAuthenticated();
That means that the user is authenticated.
But when I use the logoutRedirect function to logout the user. it is properly getting redirected to the logout-redirect-uri. But, it is still persisting the session somehow. Again if I try to login it is not asking for the credentials. Instead, it is taking me to the screen when it will ask me to sent the token to my registered mobile number.
await instance.logoutRedirect();
Can anybody suggest a way to remove the entire session and ask the user to enter the credentials again after logging out?

Related

Background Access to microsoft Graph API

i'm developing a single page application for a costumer. I need to create a script that allows me to access to my app without user interaction. for example i press a button and the script automatically log me in (i know username and password of the user). The user don't need to see the window where i put username and password.
Is it possible? at the moment my login script is:
const authResult = await msalClient.loginPopup(msalRequest);
localStorage.setItem('msalAccount', authResult.account.username);
// Get the user's profile from Graph
user = await getUser();
// Save the profile in session
localStorage.setItem('graphUser', JSON.stringify(user));
if(accountAttivo!=""){
setActiveUser();
}
updatePage(Views.home);
Looks like you are trying to follow the ROPC flow as you are using username and password credentials in your script, access token must be fetched from AAD before we call getUser(). To fetch any details using graph api we need to have access token please go through the article which helps you more in understanding.
Let's say we wrote a function called getAccessToken() to fetch the token. Once the token fetched and is saved in the sessions, following code can be used in getUser() to fetch the user profile.
const options = {
authProvider,
};
const client = Client.init(options);
let res = await client.api('/me')
.get();
Calling both the functions getAccessToken() and getUser() in the code flow of the button click event should bypass the user interaction with the application to enter credentials.
NOTE: Microsoft does not recommend to user ROPC flow. This most scenarios, more secure alternatives are available and recommended.
This flow requires a very high degree of trust in application, and
carries risks which are not present in other flows. You should only
use this flow when other more secure flows can’t be used.

Azure App Service Easy Auth

I have an Azure mobile backend set up with easy auth for facebook and google authentication and it works as expected.
Every time a user signs in with any of the supported providers, I want to be able to verify if it's a new user or not (e-mail not in database), without make an additional call from client. Is this possible?
Every time a user signs in with any of the supported providers, I want to be able to verify if it's a new user or not (e-mail not in database), without make an additional call from client. Is this possible?
As far as I know, we couldn't directly verify if it's a new user or not.
No matter you use server flow or client flow, easy auth will just return access token for the client to access the mobile backend resources, it will not check the user is new or old.
If you want to achieve this requirement, you need write your own logic.
You could write codes after the user login successfully.
For example, facebook login.
If you the use have login successfully,you could call GetAppServiceIdentityAsync extension method to get the login credentials, which include the access token needed to make requests against the Facebook Graph API.
// Get the credentials for the logged-in user.
var credentials =
await this.User
.GetAppServiceIdentityAsync<FacebookCredentials>(this.Request);
if (credentials.Provider == "Facebook")
{
// Create a query string with the Facebook access token.
var fbRequestUrl = "https://graph.facebook.com/me/feed?access_token="
+ credentials.AccessToken;
// Create an HttpClient request.
var client = new System.Net.Http.HttpClient();
// Request the current user info from Facebook.
var resp = await client.GetAsync(fbRequestUrl);
resp.EnsureSuccessStatusCode();
// Do something here with the Facebook user information.
var fbInfo = await resp.Content.ReadAsStringAsync();
}
Then you could check the database according to the user information.
More details about how to get user information in server side, you could refer to How to: Retrieve authenticated user information.

chrome.identity.LaunchWebAuthFlow: How to implement logout in a web app using oauth2

I am working on some client side web app like a chrome extension that needs access to outlook mail and calendar. I followed the instruction on https://dev.outlook.com/RestGettingStarted and successfully got access and refresh tokens to retrieve data.
However, I cannot find any way of implementing "logout". The basic idea is to let user sign out and login with a different outlook account. In order to do that, I removed cached tokens, requested access tokens in interactive mode. The login window did pop out, but it took any valid email address, didn't let me input password and finally returned tokens for previous account. So I was not able to really use a different account until the old token expired.
Can anyone please tell me if it is possible to send a request to revoke the tokens so people can use a different account? Thanks!
=========================================================
Update:
Actually it is the fault of chrome.identity api. I used chrome.identity.LaunchWebAuthFlow to init the auth flow. It caches user's identity but no way to remove it. So we cannot really "logout" if using this api.
I used two logouts via launchWebAuthFlow - first I called the logout link to my app, then secondly, I called the logout link to Google.
var options = {
'interactive': false,
'url': 'https://localhost:44344/Account/Logout'
}
chrome.identity.launchWebAuthFlow(options, function(redirectUri) {});
options = {
'interactive': false,
'url': 'https://accounts.google.com/logout'
}
chrome.identity.launchWebAuthFlow(options, function(redirectUri) {});

Azure Active Directory Logout with ADAL library

I used the my Azure Active Directory to protect my web API and I create a native application in the Azure management portal. This native application is basically a MVC web application and I use the ADAL library to get the token and call the api with that token. The code I used to get the token is shown below:
AuthenticationContext ac = new AuthenticationContext(authority);
AuthenticationResult ar = ac.AcquireToken(resourceID, clientID, redirectURI);
string accessToken = ar.AccessToken;
Now I need to logout and switch to another user but somehow the user credentials are remembered by the system. I clear the token cache in the authentication context and post logout api request as follows where *** is my tenant ID.
//Log out after api call
ac.TokenCache.Clear();
string requestUrl = "https://login.windows.net/***/oauth2/logout";
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
var response = await client.SendAsync(request);
The api call succeeds but the logout doesn't work.
What should I do to logout and switch to another user?
I don't think this would work. You would need to redirect the user to logout URL for logout to work.
Here's how you can create a logout URI:
https://login.microsoftonline.com/{0}/oauth2/logout?post_logout_redirect_uri={1}
Where:
{0} - Fully qualified name of your Azure Active Directory e.g. yourad.onmicrosoft.com or tenant id.
{1} - The URL of your application where a user must be redirected back after the logout is complete. This should be properly URL encoded.
If you goal is to sign in a s a different user, you don't strictly need to log out the first user from its session with Azure AD. You can pass PrompBehavior.Always in your AcquireToken call, so that you will be guaranteed to prompt the user with a clean credential gathering UX.
Note: if you want to wipe every trace of the first user from the app you can keep the cache cleanup code you have. ADAL allows you to keep tokens for multiple users tho, hence if your app as multi-user functions this might be useful - the catch is that if you do so, at every AcquireToken you'll have to also specify which user you want a token for or ADAL won't know which one to return. If you don't need multiple users at once, the cache cleanup + PromptBehavior.Always remains the easiest path.
You can do this for clear cache :
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
CookieSyncManager.getInstance().sync();
mAuthContext.getCache().removeAll();

everyauth always triggers authorization

I am using everyauth in my expressjs app to do oauth authentication & authorization with 37signals site. However, this is a general oauth question.
When the user accesses my app the first time, he authenticates and authorizes my app from 37signals site. He is then redirected to my app, where I save the user info in Database along with the access token. Now lets say, the user logs out. If he tries to login, he is forced to authorize my app again. This is not right. I expected everyauth to bypass the authorization step, since it was already done once. This is usually done, by passing the refresh token while starting the oauth flow with the oauth provider site. But I am not sure how everyauth is handling the second time login. Can somebody throw some light on this?
I start the oauth flow when the user tries to login by redirecting him to http://localhost/auth/37signals.
Here is the everyauth code I am using,
everyauth['37signals']
.appId('e6e76726501abf1b5627fe854b384ef8d62d7a55')
.appSecret('7c6891f46cb19aaf1831785968630ed4a1b3c342')
.findOrCreateUser( function (sess, accessToken, accessSecret, _37signalsUser) {
console.log('inside findOrCreateUser');
console.log(util.inspect(_37signalsUser));
var promise = this.Promise();
users.findOrCreateUser(_37signalsUser, accessToken, accessSecret, promise);
return promise;
})
.redirectPath('/authenticated');
I implemented the twitter strategy and have the same problem here as well. The approval screen (Authorize app name to use your account) appears every time the user logs in after logging out.
Looks like this is not supported according to this thread
https://groups.google.com/forum/?fromgroups=#!searchin/37signals-api/refresh/37signals-api/B59BS-CMxfs/pf3NsaHMUN4J

Resources