Claims augmentation with OWIN but outside of Startup code


Claims list included in the ClaimsPrincipal usually originate from the security token received by the application as part of user authentication (SAML, OpenIDConnect id token) or access authorization (OAuth2 bearer access token).  However, sometimes there is a need to modify that list with claims derived from other sources:

  1. Attributes retrieved from custom databases
  2. Attributes not initially included in the security token but which can be retrieved from the Security Token Service (e.g. Azure AD via Graph API).

Usually such token augmentation is done as soon as the initial security token is validated, e.g. http://www.cloudidentity.com/blog/2015/08/26/augmenting-the-set-of-incoming-claims-with-the-openid-connect-and-oauth2-middleware-in-katana-3-x/.

In order to accomplish #2 above the application will need an access token to Azure AD (assuming that is the STS used by the application). In that case the earliest event when this can be accomplished in a regular web application using OpenIDConnect authentication is when the authorization code returned together with the id token is converted into an AAD access token, i.e. in the AuthorizationCodeReceived delegate.

Occasionally, however an application may need to modify the claims list much later, in the regular application code rather than Startup.auth.cs. What is important though is that not only the memory list is modified but that the list is then serialized to the authentication cookie for future use if the application is using cookies. Theoretically, that should be possible by adding a new ClaimsIdentity to the ClaimsPrincipal. However, OWIN in ASP.NET 4 will not serialize the new identity. An alternative method is to modify the existing ClaimsIdentity as follows:

var id = (ClaimsIdentity)(ClaimsPrincipal.Current.Identity);

id.AddClaim(new Claim("Extra", "Extra claim"));

Request.GetOwinContext().Authentication.SignIn(id);

The new 'Extra' claim will now be associated with the current ClaimsPrincipal in all subsequent requests for this user.

Comments (2)

  1. In my scenario (AAD B2C, Graph, Asp.Net MVC5 web app OWIN calls Web API 2 with Bearer token) my web app calls the graph API and allows user to select one of the user groups they are a member of. That group ID is to be added to the identity as a new claim. From there, I need that claim to be included in the bearer token used to call my API. Your example gets me most of the way… After SignIn(), I see the claim is part of my ClaimsIdentity. However, when I get the token (AcquireTokenSilentAsync) I see that the token doesn’t include that claim. What do I need to do to ensure the token contains this information?

    1. SailingRock says:

      You can’t do it: only the issuer, who signed the token – in this case B2C – can decide what claims to include in it. Your MVC application trusts B2C and obviously trusts itself – therefore it can modify the list of claims for its own use. However, the Web API has no reason to trust that your MVC application the same way it trusts B2C. To accomplish what you want to do, you will need to pass the group data as part of the payload.

Skip to main content