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.