Transforming Open Id Connect claims in ASP.Net Core

You can implement OnSigningIn event of SignInScheme. Here is an example:

        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AuthenticationScheme = "OpenIdCookies",
            AutomaticAuthenticate = true,
            Events = new CookieAuthenticationEvents()
            {
                OnSigningIn = async (context) =>
                {
                    ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
                    identity.Claims = identity.Claims.Where(...);
                }
            }
        });

        var oidcOptions = new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "OpenIdCookies"
        };

        //.. set other options

        app.UseOpenIdConnectAuthentication(oidcOptions); 

Thank you Adem for your reply... it solved the vast majority of the problem... the only issue being that identity.Claim is a read only property. I found creating a new Principal did work though:

Events = new CookieAuthenticationEvents()
{
    OnSigningIn = (context) =>
    {
        ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;

        var givenName = identity.FindFirst(Constants.ClaimTypes.GivenName);
        var familyName = identity.FindFirst(Constants.ClaimTypes.FamilyName);
        var sub = identity.FindFirst(Constants.ClaimTypes.Subject);

        var claimsToKeep = new List<Claim> {givenName, familyName, sub};

        var newIdentity = new ClaimsIdentity(claimsToKeep, identity.AuthenticationType);

        context.Principal = new ClaimsPrincipal(newIdentity);

        return Task.FromResult(0);
    }
}

Whether this is the correct approach I'm not sure, but it appears to work.


I like LeastPrivilege's suggestion to transform earlier in the process. The code provided doesn't quite work. This version does:

var oidcOptions = new OpenIdConnectOptions
{
   ...

   Events = new OpenIdConnectEvents
   {
       OnTicketReceived = e =>
       {
          e.Principal = TransformClaims(e.Ticket.Principal);
          return Task.CompletedTask;
       }
   }
};

This replaces the Principal rather than the Ticket. You can use the code from my other answer to create the new Principal. You can also replace the Ticket at the same time but I'm not sure it is necessary.

So thank you to LeastPrivilege and Adem for suggesting ways that pretty much answered my question... just the code needed slight adjustments. Overall, I prefer LeastPrivilege's suggestion of transforming claims early.