Azure App Service Easy Auth - azure

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.

Related

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

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?

Can an open id connect id token be used to authenticate to an api

I am building a mern application.
the backend built using express exposes an api which users can create data and access the data they have created.
I want to allow users to sign in with google and get authorization to create and access the resources on this api which i control (not on google apis).
I keep coming across oauth 2 / open id connect articles stating that an Id token is for use by a client and a access token provided by a resource server should be used to get access to an api.
e.g. https://auth0.com/blog/why-should-use-accesstokens-to-secure-an-api/
the reason stated for this is that the aud property on the id token wont be correct if used on the api.
I realise that some sources say: that if the spa and api are served from same server and have same client id and therefore audience I can use and id token to authenticate to the api, but I am looking to understand what I can do when this is not the case?
I feel using oauth2 for authorization is overkill for my app and I cant find any information about how to use open id connect to authenticate to my api.
Surely when you sign in to Auth0 authourization server using google it is just requesting an open id connect id token from google?
I am wondering if using Authorization Code Grant flow to receive an id token on the api server would allow me to authenticate a user to my api?
in this case would the api server be the client as far as open id connect is concerned and therefore the aud value would be correct?
I can generate an url to visit the google oauth server using the node googleapis library like so:
const { google } = require("googleapis");
const oauth2Client = new google.auth.OAuth2(
'clientid','clientsecret',
"http://localhost:3000/oauthcallback",//this is where the react app is served from
);
const calendar = google.calendar({ version: "v3", auth: oauth2Client });
const scopes = ["openid"];
const url = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: "offline",
// If you only need one scope you can pass it as a string
scope: scopes,
});
async function getUrl(req, res) {
console.log(url)
res.status(200).json({
url,
});
}
and use the following flow.
You are not supposed to access any API's using the ID-Token. First of all the life-time of the ID-token is very short, typically like 5 minutes.
You should always use the access-token to access API's and you can using the refresh token get new access-tokens. The ID-token you can only get one time and you use that to create the local user and local cookie session.
If you are using a SPA application, you should also consider using the BFF pattern, to avoid using any tokens in the SPA-Application
see The BFF Pattern (Backend for Frontend): An Introduction
I agree with one of the commenters that you should follow the principle of separation of concern and keep the authorization server as a separate service. Otherwise it will be a pin to debug and troubleshoot when it does not work.

How to get user details from an Azure AD token?

Using this tutorial as a guide: https://github.com/Azure-Samples/ms-identity-javascript-angular-spa-aspnetcore-webapi
In the web api we need to obtain the users details (for audit purposes we want to record the details of the user in the database).
In the web api, is there a way to decode the azure token to obtain the user details? Or we could simply pass the user email from the client browser in each request also be feasible (this is easily accessible using the MSAL library for Angular)
Rather than trying to decode the token to get the current users email, the base controller exposes the current user as detailed here;
https://learn.microsoft.com/en-us/aspnet/core/migration/claimsprincipal-current?view=aspnetcore-2.1
So simply using the following I can obtain the user associated with the current request;
string email = User.FindFirstValue(ClaimTypes.Email);
You could decode token to get some information of the signed-in user such as username and email, try token with https://jwt.io/.
If you want more details, you can use MS Graph. Me means current signed-in user. Try with following Graph SDK or HttpClient sample.
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
// or graphClient.Users[user-object-id].Request().GetAsync(); for a specific user
var user = await graphClient.Me
.Request()
.GetAsync();

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 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();

Resources