zoukankan      html  css  js  c++  java
  • Asp.net Core 2.0 OpenId Connect Handler缺失Claims?

     

    原文:https://leastprivilege.com/2017/11/15/missing-claims-in-the-asp-net-core-2-openid-connect-handler/
    发布于:2017年11月
    环境:ASP.NET Core 2.0

    通过OIDC provider 把Claims映射到ClaimsPrincipal这一步骤,在ASP.NET Core 2中新的OpenID Connect handler具有不同的行为。
    这是特别令人困惑和难以诊断的,因为这里有几个部件聚集在一起。我们来看一下。
    您可以使用我的示例OIDC客户端来观察到相同的结果。

    将标准claim类型映射到Microsoft专有claim类型

    一件令人烦恼的事情是微软仍然认为他们知道什么是最适合你的,将OIDC标准声明映射到其专有声明。
    可以通过清除Microsoft JWT令牌处理程序上的入站声明类型映射来优雅地修复:

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    基本的OpenId Connect授权请求

    接下来,让我们从客户端请求openid scope的场景开始。
    首先令人困惑的是Microsoft使用openid和profile scope预先在OpenIdConnectOptions上填充了Scope集合。这意味着如果你只想请求openid,你首先需要清除Scope集合,然后手动添加openid。

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
        .AddCookie("Cookies", options =>
        {
            options.AccessDeniedPath = "/account/denied";
        })
        .AddOpenIdConnect("oidc", options =>
        {
            options.Authority = "https://demo.identityserver.io";
            options.ClientId = "server.hybrid";
            options.ClientSecret = "secret";
            options.ResponseType = "code id_token";
     
            options.SaveTokens = true;
                        
            options.Scope.Clear();
            options.Scope.Add("openid");
                        
            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name", 
                RoleClaimType = "role"
            };
        });

    使用ASP.NET Core v1处理程序,将返回以下声明:nbf,exp,iss,aud,nonce,iat,c_hash,sid,sub,auth_time,idp,amr。

    在V2中我们只能得到sid,sub和idp。发生了什么?

    微软在其OpenID Connect handler中添加了一个名为ClaimActions的新概念。Claim actions用来实现自外部provider的claim如何映射(或不)到您的ClaimsPrincipal中的claim。查看OpenIdConnectOptions的构造函数,您可以看到,处理程序现在默认会跳过以下声明:

    ClaimActions.DeleteClaim("nonce");
    ClaimActions.DeleteClaim("aud");
    ClaimActions.DeleteClaim("azp");
    ClaimActions.DeleteClaim("acr");
    ClaimActions.DeleteClaim("amr");
    ClaimActions.DeleteClaim("iss");
    ClaimActions.DeleteClaim("iat");
    ClaimActions.DeleteClaim("nbf");
    ClaimActions.DeleteClaim("exp");
    ClaimActions.DeleteClaim("at_hash");
    ClaimActions.DeleteClaim("c_hash");
    ClaimActions.DeleteClaim("auth_time");
    ClaimActions.DeleteClaim("ipaddr");
    ClaimActions.DeleteClaim("platf");
    ClaimActions.DeleteClaim("ver");

    如果您想“取消”跳过某项声明,则需要在设置handler时删除特定声明。以下是获取amr声明的非常直观的语法:

    options.ClaimActions.Remove("amr");

    从OIDC provider请求更多的Claim

    当你要求更多的范围时,例如个人资料或自定义范围导致更多索赔,还有另一个令人困惑的细节需要注意。
    根据OIDC协议中的response_type,某些声明通过id_token进行传输,有些通过userinfo端点进行传输。我在这里写了关于此细节的文章
    因此,首先您需要在处理程序中启用对userinfo端点的支持:

    options.GetClaimsFromUserInfoEndpoint = true;

    如果声明由userinfo返回,ClaimsActions将用于从返回的JSON文档映射claim到principal。这里使用以下默认设置:

    ClaimActions.MapUniqueJsonKey("sub", "sub");
    ClaimActions.MapUniqueJsonKey("name", "name");
    ClaimActions.MapUniqueJsonKey("given_name", "given_name");
    ClaimActions.MapUniqueJsonKey("family_name", "family_name");
    ClaimActions.MapUniqueJsonKey("profile", "profile");
    ClaimActions.MapUniqueJsonKey("email", "email");

    如果您向您的客户发送的不属于上述列表的claim,它会被忽略,您需要进行明确的映射。例如您希望客户端通过userinfo(标准OIDC声明之一,但不幸未由Microsoft映射)获得website claim - 您需要自行添加映射:

    options.ClaimActions.MapUniqueJsonKey("website", "website");

    这同样适用于您通过userinfo返回的任何其他声明。

    我希望这有帮助。简而言之 – 你应该明确的知道你的映射,因为我相信这些默认映射将在可能会发生变化,这将导致您的客户端应用程序出现意外行为。

  • 相关阅读:
    javascript类的封装『转』
    闭包概念
    继承
    理解面向对象
    cookie的使用
    开园啦。。。
    Myslq 之常用命令
    Myslq 之修改提示符
    Myslq 之登陆、退出
    Javascript 之 Number
  • 原文地址:https://www.cnblogs.com/lookerblue/p/11098414.html
Copyright © 2011-2022 走看看