Context for getting access token that needs to be passed to Graph API - azure-active-directory

On my initial analysis on the fetching the access token from Azure AD using OpenID connect protocol, I came to know that there are two ways to consider
Fetching access token using the signed in user's context where caching is used.
Fetching access token using application context.
Can anyone help me to know which needs to be consider with some example code.

Fetching access token using the signed in user's context where caching is used.
OpenID Connect implements authentication as an extension to the OAuth 2.0 authorization process. It provides information about the end user in the form of an id_token that verifies the identity of the user and provides basic profile information about the user.
Please refer to code sample :Calling a web API in a web app using Azure AD and OpenID Connect ,this sample uses the OpenID Connect ASP.Net OWIN middleware and ADAL .Net. In controller , you could get access token for specific resource using the signed in user's context :
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID));
ClientCredential credential = new ClientCredential(clientId, appKey);
result = await authContext.AcquireTokenSilentAsync(todoListResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
Fetching access token using application context.
What do you mean by "application context" ? If you are talking about OAuth 2.0 Client Credentials Grant Flow , which permits a web service (confidential client) to use its own credentials instead of impersonating a user, to authenticate when calling another web service. You could refer to this scenario explanation and code samples .

To fetch an access token to the graph API, you need to:
redirect the user to the Azure authorization endpoint (https://login.microsoftonline.com/common/oauth2/v2.0/authorize),
to get back an authorization token,
that you need to provide Azure with, on the access token endpoint (https://login.microsoftonline.com/common/oauth2/v2.0/token), with your application credentials.
Finally, you can provide this access token to the userinfo endpoint on the graph API: https://graph.microsoft.com/v1.0/me
with some example code
I've written a sample code, but it depends totally on the language, environment and OIDC library you are using. In case you are using Java in a servlet environment with the MIT implementation of OIDC (MITREid Connect), my example to access the Microsoft graph API by means of OIDC on Azure is available on GitHub here: https://github.com/AlexandreFenyo/mitreid-azure

Related

Spring OAuth2 Single Page Application Integration to Azure

I have been tasked with integrating Azure Active Directory Authorization into one of our applications and have tried out some of the samples with relative success.
I have a Javascript SPA application (GoogleWebToolkit) that communicates with a Spring REST (not Boot) API. The Rest API is currently secured with Spring Security and login URL username/password etc.
I want to change this to use Azure OAuth2.
Being new to OAuth2 I'm trying to figure out if I should be using either of the following Spring options.
With this option all the configuration is done at the server side, client id,secret
If I do a href from the SPA front end to 'oauth2/authorization/AzureAD' URL, its sends a redirect to the Azure Login page, allows authentication and redirects back to what redirect URL I enter into the Azure AD console configuration. This works to a degree but trying to extract the token and pass it back is not working so far.
http.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService())
.authorizationEndpoint()
.authorizationRequestResolver(
new CustomAuthorizationRequestResolver(
clientRegistrationRepository(),
#Bean
public ClientRegistration clientRegistration() {
ClientRegistration.Builder builder = ClientRegistration.withRegistrationId("AzureAD");
builder.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
........................
or
I haven't fully tried this option yet, but I think it involves doing the authorization directly from the SPA javascript front end, put all the values for the client id/secret into the javascript FE etc, and then passing the once acquired token via the Auth header for validation by the server side. Like at https://www.baeldung.com/spring-security-oauth-jwt
.oauth2ResourceServer()
.jwt()
.jwkSetUri("https://login.microsoftonline.com/common/discovery/v2.0/keys");
Could someone confirm where I should be using Option 1 or 2, and if I am understanding things properly?
Your understanding is correct in option 2. As per above scenario, let’s consider Front End Application which is Single Page Application (Java Script) to be OAuth Client App to orchestrate the process of obtaining access token and then grant access to resources from Spring back-end application.
So, here client Application need to be registered in Azure AD to acquire the access token secured by Azure AD.
We recommended MSAL libraries which helps to acquire tokens from the Microsoft identity platform and handle token in many ways to authenticate users and access secured web APIs.
Both the applications (front end and back end) need to register in Azure AD based on the scenario.
Update client-id, tenant-id, redirect URI to front end application configuration file based on application registration in Azure AD.
Back-end application also need to be registered in Azure Ad to secure by Microsoft Identity which can then define the delegated permissions(scopes) your API exposes.
Then business logic needs to add in back-end application to determine what is allowed or prohibited based on these scopes in access token.
To authorize the client request in Spring application:
Users will start by authenticating with a username and password in front end application.
Once authenticated, the client will receive a JWT representing an access token.
The client will include the access token in the authorization header of every request to a secure endpoint.
The resource server will validate the access token and determine if it has the right permissions, using the information within the token.
In this case, Spring serves as resource server and not acquiring any token in the back-end application .
Security Configuration in Spring provides numerous methods to add filters to the HTTP request to authenticate each request.
Here,
http.cors() will allows Cross-Origin Resource Sharing (CORS) checks to succeed.
All the requests need to authenticate before passing to the application(controllers).
Spring application serve as a resource server and authentication should be provided via JWT access tokens and further validate the roles and scopes in the application’s controller using #AllowedRoles annotation.
Our JWT access tokens are signed by Azure AD and application should check if their signature is correct. Azure AD has an endpoint with the public key to do so, which need to configure in spring application.
Also, as mentioned, we will need access token to call the protected back-end application because contents of the token are intended for the resource (back-end API) to perform authentication and authorization.
To validate the token, you can search the keys endpoint in the discovery document and then provide this JSON web key (JWK) endpoint straight away where JWK URI can be found.
# application.properties
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.windows.net/common/discovery/keys
Note: The flow would be same to get the access token while integrating with Azure AD. i.e in Spring boot or in spring.

Microsoft graph api access

I need a solution for accessing Microsoft graph api with a token which never expires for a multitenant application.
I am using frontend as react and backend as lambda function.
Actual requirement
Need to connect Microsoft app (which will give access to graph api's) with project where same auth will be used by multiple users, same authentication should work until it revoked.
Take OAuth 2.0 auth code grant as an example.
Currently, access token lifetime cannot be configured to be permanent.
Therefore,You can Request an access token
and you can Refresh the access token when it expired.

Jhipster Azure AD Access token

I am using Azure AD access token instead of default openID connect server (keycloak) to protect the backend REST API. Could you please let me know if i need to make any changes for AuidenceValidator class under package security.oauth2.
Application flow:
UI(React JS) will access the Spring boot API by passing access token.
Please take a look at the ms-identity-java-webapi sample. The msal-obo-sample shows how to validate an access token acquired by MSAL using Spring Security. You will be interested specifically in AADClaimsVerifier and SecurityResourceServerConfig

Custom Azure B2C sign up policy - client credential authorisation flow for business logic API

I am currently following this user guide for adding a custom policy to my B2C sign up process
I have created the API and configured the various XML files. I can generate a token to access the API via the implict flow.
The API is secured under the app service with Azure Active Directory authentication.
The page linked to describes how to add basic authentication and a client ID / secret, which is a Client Credentials flow, so I was trying to test this in postman
However, having failed to get it to work I went looking and found a variety of posts stating implict credentials are not supported by Azure B2C?
If that is the case I'm puzzled how it is I'm supposed to ensure the claims of the API I am calling to carry out the business logic can be accessed by the custom policy?
My API is hosted on Azure in the same subscription. I can generate tokens for this API fine to use within my native / client app.
Please could someone advise how I should go about testing access to this API from a B2C context via Postman?
The page linked to describes how to add basic authentication and a client ID / secret, which is a Client Credentials flow, so I was trying to test this in postman
To be exact, it should not be called Client Credentials, because it isn't it.
It's just HTTP Basic authentication.
You are adding an alternative authentication method to your API in that case.
The fact that B2C does not support client credentials auth does not matter here.
What matters is that you have enabled AAD authentication on App Service.
This will block the calls that try to use Basic auth against your API.
Here are a couple options that you can do:
Disable authentication on the App Service and implement the two alternative authentication methods in your API code
Allow anonymous calls through from App Service auth and implement Basic auth for unauthenticated requests in your API code
As for testing from Postman, it should then be the same as testing any API supporting Basic authentication.
You don't authenticate against B2C, so there is nothing special about it.

Access Token for both Microsoft Graph and Custom API

I have a ReactJs frontend making requests to an API. Both hosted in Azure with app registrations in AAD as well.
I used to be able to use v1.0 auth endpoint, and create a valid token for the API:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=<AAD_WEB_APP_ID>&resource=<AAD_API_ID>&response_type=token ...
If I understand the documentation correctly, this type of auth flow isn't allowed/possible in v2.0:
However, that Web API can receive tokens only from an application that has the same Application ID. You cannot access a Web API from a client that has a different Application ID. The client won't be able to request or obtain permissions to your Web API.
The reason for changing from v1.0 to v2.0 is that I need access to Microsoft Graph (Groups in particular).
My question is: How can I create an access_token that works for Microsoft Graph and my API? If that isn't possible, what would the correct auth flow be?
You don't need to switch to the v2 Endpoint for this, Microsoft Graph supports both v1 and v2 tokens (actually, every API I can think of that supports v2 also supports v1 but there might be an exception I'm forgetting).
The steps are pretty straightforward:
Update your AAD registration in the Azure Portal and add the Permissions for Microsoft Graph you're going to be using.
Instead of passing resource=<AAD_API_ID> in your URI, use resource=graph.microsoft.com. This will return a token that can be used with Microsoft Graph.
Important: You must request the Offline Access scope (offline_access) for this to work.
Where this gets confusing is that technically you cannot use the same Access Token to access both your API and Microsoft Graph. What is supported is switching the Resource when refreshing your token. So while, yes, you are using two different tokens, you're reusing the same credentials/authorization code.
Here is an example flow:
A user authenticates using your API as the Resource (resource=<AAD_API_ID>). This returns an Authorization Code back to your application.
The application posts the Authorization Code to the /token endpoint (also using your API as the Resource). This will return both an access_token and a refresh_token to the application.
Use this access_token to make calls into your API.
The application posts the refresh_token to the /token endpoint using graph.microsoft.com as the Resource. This will return a new access_token and refresh_token keyed to Microsoft Graph.
Use this new access_token to make calls into Microsoft Graph.
The application again posts the refresh_token to the /token endpoint but this time using your API as the Resource again. This will return a new access_token and refresh_token keyed to your API.
Call your API
You can repeat this cycle as needed. Depending on how often you need to switch, you can also keep access tokens for both your API and Graph in memory and reuse them until they expire. Just be sure and always store the last Refresh Token you received so you can fetch a refreshed token for either resource as needed.

Resources