Transforming Open Id Connect claims in ASP.Net Core

前端 未结 4 822
时光说笑
时光说笑 2020-12-30 05:58

I\'m writing an ASP.Net Core Web Application and using UseOpenIdConnectAuthentication to connect it to IdentityServer3. Emulating their ASP.Net MVC 5 sample I\'

相关标签:
4条回答
  • 2020-12-30 06:27

    I personally prefer to do the claims transformation in the middleware where the actual authentication happens.

    You can use the OnTicketReceived event on the OIDC middleware for that.

    var oidcOptions = new OpenIdConnectOptions
    {
       AuthenticationScheme = "oidc",
       SignInScheme = "cookies",
    
       Authority = Clients.Constants.BaseAddress,
    
       ClientId = "mvc.hybrid",
       ClientSecret = "secret",
       ResponseType = "code id_token",
       SaveTokens = true,
    
       TokenValidationParameters = new TokenValidationParameters
       {
          NameClaimType = JwtClaimTypes.Name,
          RoleClaimType = JwtClaimTypes.Role,
       },
    
       Events = new OpenIdConnectEvents
       {
           OnTicketReceived = e =>
           {
               ClaimsPrincipal p = TransformClaims(e.Ticket.Principal);
               e.Ticket = new AuthenticationTicket(
                p,
                e.Ticket.Properties,
                e.Ticket.AuthenticationScheme);
    
            return Task.CompletedTask;
        }
      }
    };
    
    0 讨论(0)
  • 2020-12-30 06:30

    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); 
    
    0 讨论(0)
  • 2020-12-30 06:37

    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.

    0 讨论(0)
  • 2020-12-30 06:38

    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.

    0 讨论(0)
提交回复
热议问题