在ASP.Net Core中转换Open Id Connect声明

Pie*_*son 11 claims-based-identity identityserver3 asp.net-core

我正在编写ASP.Net核心Web应用程序并使用UseOpenIdConnectAuthentication它将其连接到IdentityServer3.模拟他们的ASP.Net MVC 5样本我正在尝试转换从Identity Server收到的声明,以删除" 当然不需要的低级协议声明 ".在MVC 5中,他们为SecurityTokenValidated Notification添加了一个处理程序,该处理程序AuthenticationTicket仅使用所需的声明来交换一个.

在ASP.Net Core中,为了做同等的事情,我认为我需要处理OnTokenValidatedOpenIdConnectEvents.但是,在该阶段,似乎没有检索到附加范围信息.如果我处理OnUserInformationReceived,则存在额外信息,但存储在用户而不是主体上.

在身份验证完成后,其他事件似乎都不是永久删除我不想保留的声明的明显位置.任何建议都感激不尽!

Pie*_*son 10

我喜欢LeastPrivilege建议在此过程中进行转换.提供的代码不太有效.这个版本有:

var oidcOptions = new OpenIdConnectOptions
{
   ...

   Events = new OpenIdConnectEvents
   {
       OnTicketReceived = e =>
       {
          e.Principal = TransformClaims(e.Ticket.Principal);
          return Task.CompletedTask;
       }
   }
};
Run Code Online (Sandbox Code Playgroud)

这取代了Principal而不是Ticket.您可以使用我的其他答案中的代码来创建新代码Principal.你也可以同时更换,Ticket但我不确定是否有必要.

所以,感谢LeastPrivilege和Adem建议几乎回答我问题的方法......只需要对代码进行微调.总的来说,我更喜欢LeastPrivilege建议尽早转换索赔.


lea*_*ege 6

我个人更喜欢在实际身份验证发生的中间件中进行声明转换。

为此,您可以使用 OIDC 中间件上的 OnTicketReceived 事件。

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;
    }
  }
};
Run Code Online (Sandbox Code Playgroud)


ade*_*lin 5

你可以实现的OnSigningIn事件SignInScheme.这是一个例子:

        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); 
Run Code Online (Sandbox Code Playgroud)


Pie*_*son 5

感谢Adem的回复...它解决了绝大多数问题......唯一的问题是identity.Claim是一个只读属性.我发现创建一个新的Principal确实有效:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是否是正确的方法,我不确定,但它似乎工作.