zoukankan      html  css  js  c++  java
  • [翻译]在asp.net core2.0 OpenID Connect Handler中丢失了声明(CLaims)?

    注:这是一篇翻译,来自这里。这篇文章讲述了在asp.net core2.0中使用openid connect handler的过程中解析不到你想要的claim时,你可以参考这篇文章。

    Missing Claims in the ASP.NET Core 2 OpenID Connect Handler?

    当从OIDC provider(identity provider,idp)中将claims映射到ASP.NET Core 2中的ClaimsPrincipal时,新的OpenID Connect Handler表现出了一些不同的行为。

    这种情况看起来特别令人困惑和难以诊断,因为这里有几个变化的部分。让我们看看。

    你也可以从这里下载demo来研究以下。

    Mapping of standard claim types to Microsoft proprietary ones从标准claim类型映射成Microsoft专有的

    首先让人感到恶心的是,Microsoft仍然认(意)为(淫)将OIDC标准的Claim类型映射成他们专有的类型(这种做法)对于你来说是最好的一种方式。

    令人欣慰的是,通过在Microsoft JWT令牌处理程序(token handler)中清除流入(inbound )Claim类型映射,可以很好地解决这个问题:

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    A basic OpenID Connect authentication request一个基本的OpenID Connect authentication handler请求

    接下来,让我们从一个简单的场景开始,客户端只请求openid范围(scope)。

    第一件令人困惑的事情是Microsoft会在OpenIdConnectOptions类的构造方法中预先加载openid和profile这两个请求范围。这意味着如果你只是想请求一个openid的范围,那么你必须调用一个清除的方法,然后在手动的把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");//②在添加,这样你才能只请求到openid这个scope
                        
            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name", 
                RoleClaimType = "role"
            };
        });

    在asp.net core 1.x的版本中,上述代码会返回如下claim:nbf, exp, iss, aud, nonce, iat, c_hash, sid, sub, auth_time, idp, amr.

    在asp.net core2.x的版本中,却只会返回sid, sub和idp。发生了神马??????

    Microsoft在这其中添加了一个新的概念:ClaimActions。这个类具体要做的事情是指定一个规则,来处理外部流入的claims如何去映射成为你自己的ClaimsPrincipal中的claim。查看以下OpenIdConnectOptions的构造方法,你会发现现在这个openid connect handler在默认情况下跳过了很多的映射:

    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");

    如果你不想要错过某一个claim,那你需要通过claimaction来做一些设定。如下这个方法“很直观”的将一个“amr ”的claim找了回来:

    options.ClaimActions.Remove("amr");//不想吐槽,不过这是什么狗屁名字了?希望不要产生误解,这个方法是要找回你想要的claim

    如果你想要查看所有原始的这些claim(在ClaimsPrincipal中保存的token上),那你得将claimaction从里到外处理一遍(添加一堆的Remove方法)。

    Requesting more claims from the OIDC provider从idp中获取更多的claim

    当你想要请求更多的scope,比如profile,或者一些自定义的scope,总之就是想要多一些请求范围,那么你会发些另外一些令人困惑的事情。。。

    依赖于OIDC这个协议中的response_type,一些claims是通过id token拿到的,而另一些则是通过userinfo端点拿到的。这些详细信息记录在这里

    所以,首先你需要在handler中添加对userinfo端点的支持:

    options.GetClaimsFromUserInfoEndpoint = true;

    如果claims从userinfo端点返回,那这个时候ClaimsAction又要上场了。它还是从返回的JSON document(userinfo返回的)中将claim映射到ClaimsPrincipal中。下面的代码展示了一些默认的设置:

    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");

    换句话说,如果一些发送到你客户端的claims中有一些特别的,没有存在于上面这些代码所展示的映射清单中出现,那么,那些(没有映射的)就直接被忽略了,没了,炒丢了。你得自己再显式的映射一遍:

    options.ClaimActions.MapUniqueJsonKey("website", "website");//再换句话说,OIDC中出现的标准claim,但却并没有在Microsoft中进行映射,需要你自己映射。

    同样的情形也适用于你通过userinfo返回的任何其他claim。

    希望这些讲述是有帮助的。给我的感觉就是,OAuth2.0和OpenID Connect还在发展过程中,有一些东西将来可能是有变化的,现在对映射进行显式处理,如果Mocrofost在这里把一些东西写死了,将来万一有一些变化的东西出来,那就不好弄了。

  • 相关阅读:
    [学习笔记]Nim游戏&SG函数
    [vijos1783][NOIP2012]疫情控制
    [vijos1782][NOIP2012]借教室
    [学习笔记]递推问题选讲
    [vijos1779][NOIP2012]国王游戏
    NET中使用三层构架如何从DAL层读取web.config中的数据库连接字符串!
    转:一个不错的网页进度条
    转:在没有数据时,如何使用FormView增加数据
    asp.net 2.0中的MessageBox.Show()方法
    TreeView与MultiView,View三个控件的组合使用
  • 原文地址:https://www.cnblogs.com/pangjianxin/p/9281681.html
Copyright © 2011-2022 走看看