How to obtain "B2C JWT Access Token" from the signed in User? - c#

I'm working with a .Net Core Web API and a .Net Core Web MVC Application. They both use Azure AD B2C to authenticate users. But in order to get a response from a HttpRequest from the Web API I need to provide the JWT Access Token from B2C for the signed in user on my web MVC application. Is there a way to obtain this access token inside a controller using the authenticated "User".
I have tried accessing the claims of the signed in user but no luck there, I have also used jwt.ms to review that the B2C workflow works well and that the JWT token is being generated and it works as well. The MVC application is authenticating the user and the web API is working fine with a hardcoded token. I just need to obtain the access token from a signed in user rather than doing it hardcoded.
I expect to be able to get the B2C JWT access token so that I can later on pass it to the Web Api and be able to secure my requests.

After getting some help from the MS AzureADB2C.UI GitHub crew we were able to solve the issue. The issue was that the tokens aren't saved by default on the library, so we needed to configure OIDC to specify that the tokens have to be saved for future use within the application. And so here is the example code of the "Startup" configuration and the example of how to query the "JWT access token" from the controller.
Startup.cs:
services.Configure(AzureADB2CDefaults.OpenIdScheme, options => {
options.SaveTokens = true;
});
Controller:
string idToken = await HttpContext.GetTokenAsync("id_token");
More information on how was the issue solved can be found on the following link:
https://github.com/aspnet/AspNetCore/issues/11424

You can refer to this sample application.
It uses the ASP.NET Core Azure AD B2C middleware to authenticate the end user and MSAL.NET to acquire, cache, and refresh the access token.
The access token is acquired in the AzureADB2COpenIdConnectOptionsConfigurator class.
A code example for a controller method referencing the access token is here.

Is it the actual token string you need? If so, you can access the headers using the HttpContext within the controller? The HttpContext will have a collection of headers that were passed in

Related

How to view access token generated by Azure AD in ASP.NET Core API?

How to view the access token generated by Azure AD in ASP.NET Core 5.0 Web Api?
For more context:
I have an Angular client which is getting an access token after logging in with MSAL V2. The client can call the API with the acquired access token. How can I intercept the token? I want to get the username or/and e-mail address from it.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAD"));
Use the below code to find the token from the user claim:
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
// or
identity.FindFirst("ClaimName").Value;
}
For more information you can follow the below article for more understanding:
https://visualstudiomagazine.com/articles/2019/11/01/authorization-claims.aspx
Getting the user information is quite straight forward.
In every controller, you get access to HttpContext object and that has a User property. You can check user's claims to find their name and other information about the user.

How to use OAuth 2.0 On-Behalf-Of in .netframework API

I have 2 APIs and I wanted to use OAuth 2.0 On-Behalf-Of flow to generate the token in API1 and Authorize to API2 with the generated token.
I followed https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#middle-tier-access-token-request and I was able to generate the token.
I use this following parameters:
grant_type:urn:ietf:params:oauth:grant-type:jwt-bearer
client_id:xxxxx
client_secret:xxxxxx
requested_token_use:on_behalf_of
scope:https://graph.microsoft.com/user.read
But I don't know how to authenticate to my API2 with that token and get the user and what are the next steps. My API to uses .netframework app.
I created OwinStartup and added UseWindowsAzureActiveDirectoryBearerAuthentication
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions()
{
Tenant = "xxxxxxxxxx",// Azure tenant Id
TokenValidationParameters = new TokenValidationParameters()
{
SaveSigninToken = true,
ValidAudience = "https://graph.microsoft.com"
}
});
and added Authorize attribute into my controller. but when I called the get endpoint to that controller, it gave me an error saying:
Authorization has been denied for this request.
You need to request two tokens, one is the access token of API A, and the other is the access token of API B obtained using the access token of API A as a parameter.
The document you refer to is based on the api A access token you have obtained, and there are instructions in the document.
First, you need to use the auth code flow or other login flow to obtain the access token of api A:
Then use the access token of API A as a parameter to obtain the access token of API B.
In API A I was using a wrong scope to generate token. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#middle-tier-access-token-request

ASP.NET Core: JWT token with Scopes

Background
I have a ASP.NET core (v2.1) project that contains an API. This API is access restricted by JWT bearer.
My server expose an endpoint for login:
POST http://example.com/api/login
After attaching the token to the request, I can call one of the server methods (GET or DELETE:
GET http://example.com/api/1234
or
DELETE http://example.com/api/1234
Target
I want to implement "another type" of token that will allow access only to specific scope. Let's say that we want to give access just for GET method. So, if you have this token - you can GET the resource but not to DELETE it.
Wondering if this is possible with JWT bearer token? If yes, how?
Thanks!
You shouldn't do this with the token itself. The token is used to authenticate that a user is who they claim to be. You should instead look at using the roles to authorise an action and assign different users roles to restrict access to delete verbs.
This article should be able to explain further
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.1
JWT Bearer token should be used for authentication mechanism but what you are talking about is Authorization and thus your approach is wrong seems. You should rather use the Authorization pipeline and implement proper Roles/Policy based authorization which will restrict access to those Api endpoints.

Azure AD Authentication With Auth0

I created an Azure API App and set the [Authorize] attribute on my controller and published it to Azure. Then I registered an Auth0 app, providing the data from my AD app, following Auth0's documentation. When I test the connection on their site it works just fine. I can also log in fine in my app and retrieve the access token with:
var auth0 = new Auth0Client("myUrl", "myTenant");
var user = await auth0.LoginAsync();
var accessToken = user.IdToken;
However, when I make a request to my API, passing the access token in the Authorization header, it just throws an error 401 (Unauthorized). From what the documentation says, I was under the impression this is all that should be needed, and I've not found any information to suggest otherwise. Is there an additional step to linking these?
The Solution is to configure ur API to accept tokens by that issuer, like for example by using owin middleware app.UseJwtBearerAuthentication(). Glad I could help!

Azure AD Graph API Bearer Token with ADAL JS

As Learning application , i am using AngularJS,ADAL js and WebAPI as Mentioned in this post.
Angularjs-authentication-using-azure-active-directory-authentication-library-adal
Tutorial is very neat and clean for the implementation. After the authentication i am trying to add a User in the Azure AD[The same AD i validated my credentials against].
To work with Azure AD there is Azure AD Graph API.which requires a Bearer Token.
To get The Bearer token AuthorizationContext will be used.
var authcontext = new AuthenticationContext(GraphRequest.authority);
AuthenticationResult authResult = authcontext.AcquireToken(GraphRequest.apiResourceId,
GraphRequest.clientId, GraphRequest.redirectUri);
As Authentication context is in control , so it is asking again credentials with popup. but i already have a claimPrincipal.
Is there any way i can use ClaimPrincipal to get the bearerToken ?
Have you had a chance to take a look at our public samples on GitHub?
Something like this might be useful for you to look at:
https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi
Otherwise, in general, you cannot take an ID Token and then use it to upgrade to an access token. What you can do instead is skip that login prompt, and just do the code you pasted above which obtains an access token, which can be turned into an ID token.
I hope this makes sense, please feel free to reach out with any further questions.
Shawn Tabrizi

Categories

Resources