question

NitishChauhan-2741 avatar image
0 Votes"
NitishChauhan-2741 asked Bruce-SqlWork answered

ASP.NET Persisting or Adding custom claim to access_token for Protected API

I am using OIDC/OAuth with Azure Active Directory as the IDP to allow users to login to an ASP.NET 4.6.2 MVC App with their organizational account that calls a Protected Web API. This involves authorization code flow. My code is based off the sample app provided by the Sample App=[https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect]. In the sample, instead of a Protected API, it is calling Microsoft's Graph API. I am attempting to add a custom claim to the JWT token sent to the Protected API to store some user information. Now my question...

How do I add or persist a claim to an access token obtained for the Protected API?

This is necessary for my use-case since we are integrating with an existing IDP (ourselves) and we have FK relationships based on the user_id.

Currently, I am able to obtain an access token to authorize the Client MVC App to the Protected Web API using the following code:

IConfidentialClientApplication app = MsalAppBuilder.BuildConfidentialClientApplication();

var accounts = (await app.GetAccountsAsync()).ToList();

string TodoListScope = "api://{client_id}/access_as_user";
string[] Scopes = { TodoListScope };
var tokenResult = await app.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
.ExecuteAsync()
.ConfigureAwait(false);
This code is enabled by a middleware added to Notifications object on the IAppBuilder.UseOpenIdConnectAuthentication function.

app.UseOpenIdConnectAuthentication{ new OpenIdConnectAuthenticationOptions{
...,
...,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = OnAuthorizationCodeReceived,
AuthenticationFailed = OnAuthenticationFailed,
RedirectToIdentityProvider = OnRedirectToIdentityProvider,
SecurityTokenValidated = OnSecurityTokenValidated
}
}
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
// Upon successful sign in, get the access token & cache it using MSAL
IConfidentialClientApplication clientApp =
MsalAppBuilder.BuildConfidentialClientApplication();
AuthenticationResult result = await clientApp.AcquireTokenByAuthorizationCode(new[]
{ "api://{client_id}/access_as_user" }, context.Code).ExecuteAsync();
}
I have found proposed solutions to add claims to an access token but this only adds these claims to the access_token associated with the MVC Client App Controllers NOT the Protected API. So when these claims are searched for on the claims of the JWT token for the Protected API, they are not found.

private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> arg)
{
arg.AuthenticationTicket.Identity.AddClaim(new Claim("customClaim", "customValue"));
var claimsPrincipal = new ClaimsPrincipal(arg.AuthenticationTicket.Identity);
arg.OwinContext.Request.User = claimsPrincipal;
return Task.FromResult(0);
}
If there is a solution, I assume it's on the OnAuthorizationCodeReceived function.

Thanks for any help, definitely grey-hairing a bit on this problem.

azure-ad-authenticationdotnet-aspnet-mvcazure-ad-openid-connect
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered

in your application you can add custom claims to the principle because your app is creating the principle on each request. To add a custom claim to an access token, the code must be in the producer of the access token.

typically the authentication software that produces the access token allows creating custom scopes that can return additional claims. see your authentication software/

if you are using a 3rd party authentication software, and can not add the claim, then one option is to create a new authentication endpoint. you would pass it the access token which it verified. if valid it would create a new access token with the additional claims. this token would be used instead of the original. the consumer of the new token would validate against this new endpoint rather than the original.

the endpoints could be hosted by server both sites can access. if both sites can access each other, the original site could host the endpoints.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.