4-OAuth2 & OpenID Connect & Asp net core 使用IDP

一、在 ImageGallery Client 项目启用 IDP

  1. 更改项目属性为使用 SLL, 方法同之前配置 IDP 一样
  2. 修改 IDP 项目的 Config 类中的 GetClients 方法,增加一个客户端
        public static IEnumerable GetClients()
        {
            return new List()
            {
                new Client()
                {
                    ClientName = "Image Gallery",
                    ClientId = "junguoguoimagegalleryclient",
                    AllowedGrantTypes = GrantTypes.Hybrid,
                    RedirectUris = new List()
                    {
                        "https://localhost:44314/signin-oidc"
                    },
                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile
                    },
                    ClientSecrets =
                    {
                        new Secret("junguoguosecret".Sha256())
                    }
                }
            };
        }
  1. 修改 ImageGallery.Client 的 startup 类, 支持 IDP 权限验证
  • ConfigureServices 方法增加如下:
                services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                }).AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    // IDP server 的url
                    options.Authority = "https://localhost:44319/";
                    options.ClientId = "junguoguoimagegalleryclient";
                    // specify use hybrid mode
                    options.ResponseType = "code id_token";
                    //options.CallbackPath = new PathString("oidc");
                    options.Scope.Add("openid");
                    options.Scope.Add("profile");
                    options.SaveTokens = true;
                    options.ClientSecret = "junguoguosecret";
                });
  • Configure 方法增加如下
            // 需要放在 UseMvc 前
            app.UseAuthentication();

二、权限验证实际操作

  1. 在需要增加权限的地方加上属性标记[Authorize],这里我们直接在类 GalleryController上添加
    添加如下方法
        private async Task WriteOutIdentityInformation()
        {
            // 获取保存的 identity token
            var identityToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.IdToken);

            Debug.WriteLine($"Identity token:{identityToken}");

            // 打印出 User Claims
            foreach (var claim in User.Claims)
            {
                Debug.WriteLine($"Claim type : {claim.Type} - Claim value : {claim.Value}");
            }
        }

并在 Index() 开头调用 await WriteOutIdentityInformation();
调试查看Log

IdentityServer4.Endpoints.AuthorizeEndpoint:Information: ValidatedAuthorizeRequest
{
  "ClientId": "junguoguoimagegalleryclient",
  "ClientName": "Image Gallery",
  "RedirectUri": "https://localhost:44314/signin-oidc",
  "AllowedRedirectUris": [
    "https://localhost:44314/signin-oidc"
  ],
  "SubjectId": "anonymous",
  "ResponseType": "code id_token",
  "ResponseMode": "form_post",
  "GrantType": "hybrid",
  "RequestedScopes": "openid profile",
  "State": "CfDJ8MUXARYmDzBChfPQYArN2SFocvVoTFAx3QMN6tR6pIKi3s3D5eabWiyKUI45I_TYXf3VFhHYOR8v_k97C5vARQJKugB4mGVzinSNi3-Lbn7N0tMsSH1n4iTlVdQqXCqUqSx-SEuwB3dEzJ2KnFJycV2jgDvZkcHmz5VL_F_TaCOA0moKECkjmEww1RDVJPrLvOtZtwz9lDiHCXNAdJIfHIFlFYJryZMAq9_J4O0TDTT6CHPQ1iEZMTGV_aTL17E6rov5ubPegbLtCE75KUnYxN-ujnxLY4UKqAGsmsNrz2KVGautm3500_Av-XVzQnZeD0S39eRUyCL31iY2mxHhwb8",
  "Nonce": "636690543330175298.Y2I2ODYwNzMtNTJlYi00Y2FiLTgzY2YtYjI0YjBlOWRkMDg0MDUxOGZjOTktNWViZS00MmZjLTg2MjQtMjUwODAwNWU0N2Rl",
  "Raw": {
    "client_id": "junguoguoimagegalleryclient",
    "redirect_uri": "https://localhost:44314/signin-oidc",
    "response_type": "code id_token",
    "scope": "openid profile",
    "response_mode": "form_post",
    "nonce": "636690543330175298.Y2I2ODYwNzMtNTJlYi00Y2FiLTgzY2YtYjI0YjBlOWRkMDg0MDUxOGZjOTktNWViZS00MmZjLTg2MjQtMjUwODAwNWU0N2Rl",
    "state": "CfDJ8MUXARYmDzBChfPQYArN2SFocvVoTFAx3QMN6tR6pIKi3s3D5eabWiyKUI45I_TYXf3VFhHYOR8v_k97C5vARQJKugB4mGVzinSNi3-Lbn7N0tMsSH1n4iTlVdQqXCqUqSx-SEuwB3dEzJ2KnFJycV2jgDvZkcHmz5VL_F_TaCOA0moKECkjmEww1RDVJPrLvOtZtwz9lDiHCXNAdJIfHIFlFYJryZMAq9_J4O0TDTT6CHPQ1iEZMTGV_aTL17E6rov5ubPegbLtCE75KUnYxN-ujnxLY4UKqAGsmsNrz2KVGautm3500_Av-XVzQnZeD0S39eRUyCL31iY2mxHhwb8",
    "x-client-SKU": "ID_NET",
    "x-client-ver": "2.1.4.0"
  }
}

Login 界面登陆后

IdentityServer4.Endpoints.AuthorizeCallbackEndpoint:Information: Authorize endpoint response
{
  "SubjectId": "b7539694-97e7-4dfe-84da-b4256e1ff5c7",
  "ClientId": "junguoguoimagegalleryclient",
  "RedirectUri": "https://localhost:44314/signin-oidc",
  "State": "CfDJ8MUXARYmDzBChfPQYArN2SFocvVoTFAx3QMN6tR6pIKi3s3D5eabWiyKUI45I_TYXf3VFhHYOR8v_k97C5vARQJKugB4mGVzinSNi3-Lbn7N0tMsSH1n4iTlVdQqXCqUqSx-SEuwB3dEzJ2KnFJycV2jgDvZkcHmz5VL_F_TaCOA0moKECkjmEww1RDVJPrLvOtZtwz9lDiHCXNAdJIfHIFlFYJryZMAq9_J4O0TDTT6CHPQ1iEZMTGV_aTL17E6rov5ubPegbLtCE75KUnYxN-ujnxLY4UKqAGsmsNrz2KVGautm3500_Av-XVzQnZeD0S39eRUyCL31iY2mxHhwb8",
  "Scope": "openid profile"
}

然后是 token request

IdentityServer4.Validation.TokenRequestValidator:Information: Token request validation success
{
  "ClientId": "junguoguoimagegalleryclient",
  "ClientName": "Image Gallery",
  "GrantType": "authorization_code",
  "AuthorizationCode": "7be30468050e4af46c5a806adc6abeba09755766bd1abdd3a01464e03b4fe61d",
  "Raw": {
    "client_id": "junguoguoimagegalleryclient",
    "client_secret": "***REDACTED***",
    "code": "7be30468050e4af46c5a806adc6abeba09755766bd1abdd3a01464e03b4fe61d",
    "grant_type": "authorization_code",
    "redirect_uri": "https://localhost:44314/signin-oidc"
  }
}

然后是自定义方法输出的

Identity token:eyJhbGciOiJSUzI1NiIsImtpZCI6ImM5ODExYjU4NDg5Yzk4Y2RlOTNlYWM2NmJmMjVhNzUzIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MzM0NTc3MjMsImV4cCI6MTUzMzQ1ODAyMywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMTkiLCJhdWQiOiJqdW5ndW9ndW9pbWFnZWdhbGxlcnljbGllbnQiLCJub25jZSI6IjYzNjY5MDU0MzMzMDE3NTI5OC5ZMkkyT0RZd056TXROVEpsWWkwMFkyRmlMVGd6WTJZdFlqSTBZakJsT1dSa01EZzBNRFV4T0daak9Ua3ROV1ZpWlMwME1tWmpMVGcyTWpRdE1qVXdPREF3TldVME4yUmwiLCJpYXQiOjE1MzM0NTc3MjMsImF0X2hhc2giOiJ6cUJtYjJIZmtQZk5XcnZxUlU3bVNnIiwic2lkIjoiNzc1YTRkM2E0YWY3OTQ3M2YxMTNmMmM3NjliZmVlYTMiLCJzdWIiOiJiNzUzOTY5NC05N2U3LTRkZmUtODRkYS1iNDI1NmUxZmY1YzciLCJhdXRoX3RpbWUiOjE1MzM0NTc2NzIsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.F0SVNnvhAiG9MW_BSr8YRql4KLaAGnD6xGFBDubbmmzQBGRc9198_NVQlhOtS-w9aV0daIwZaJZEvwoUS_qV03Jb_3J9VIuJ6NY44BVtnLo600KhYMlsqEoDZmjADLNqWCY4hdE-S31PXlmUNawq8jL6t9kbZRPiaSbKciAp5OHZL6UcZuAdASb-0Ivt3TE5QpwrsQ3AyHjUmYPgN4Ob3sN7wkhrDv9dD11VfZN4mtqOI-t7U3W9omloGsi22KSOBePbNQbYX3d_qcSttNyi-dW1A2TQS6WFNV8zq2ZrH-tvWU67njH-jokt10uKI7FEBAqVQ5MgApKTjahMkAlTxA
Claim type : sid - Claim value : 775a4d3a4af79473f113f2c769bfeea3
Claim type : http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier - Claim value : b7539694-97e7-4dfe-84da-b4256e1ff5c7
Claim type : http://schemas.microsoft.com/identity/claims/identityprovider - Claim value : local
Claim type : http://schemas.microsoft.com/claims/authnmethodsreferences - Claim value : pwd

复制 identity token 到 jwt.io, 可以看到解析后如下所示:

4-OAuth2 & OpenID Connect & Asp net core 使用IDP_第1张图片
image.png

  1. 添加注销登录的功能
    打开 _Layout.cshtml, 在导航栏添加如下代码
                    @if (User.Identity.IsAuthenticated)
                    {
                        
  • 注销登录
  • }

    在 Controller 的 Logout 中编写:

            public async Task Logout()
            {
                // 从 Client 端注销登录
                await HttpContext.SignOutAsync("Cookies");
                // 从 IdentityServer 注销登录
                await HttpContext.SignOutAsync("oidc");
            }
    

    运行后看日志发现有如下错误

    IdentityServer4.Validation.EndSessionRequestValidator:Information: End session request validation failure: Invalid post logout URI
    {
      "ClientId": "junguoguoimagegalleryclient",
      "ClientName": "Image Gallery",
      "SubjectId": "b7539694-97e7-4dfe-84da-b4256e1ff5c7",
      "Raw": {
        "post_logout_redirect_uri": "https://localhost:44314/signout-callback-oidc",
        "id_token_hint": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImM5ODExYjU4NDg5Yzk4Y2RlOTNlYWM2NmJmMjVhNzUzIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MzM0NTg3NDQsImV4cCI6MTUzMzQ1OTA0NCwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMTkiLCJhdWQiOiJqdW5ndW9ndW9pbWFnZWdhbGxlcnljbGllbnQiLCJub25jZSI6IjYzNjY5MDU1NTM2OTI2MDc1NS5NVGhpTm1SbE5EUXRNbVZrWXkwME0yRmxMV0l5T1RjdE9ETmxOMlUyTVRJMU1qbGxNRGt3WlRNMU5EQXRORE0wWmkwME0yVXdMVGxpTW1NdE1EZzBNamMzT0dKa01EWTUiLCJpYXQiOjE1MzM0NTg3NDQsImF0X2hhc2giOiJDZmxFZXBZQXJiblZsa3NmampteWtRIiwic2lkIjoiZjc1MjBjNzBlZTQxZWZhNWI5NjZkNmRjNWEyODkzMDUiLCJzdWIiOiJiNzUzOTY5NC05N2U3LTRkZmUtODRkYS1iNDI1NmUxZmY1YzciLCJhdXRoX3RpbWUiOjE1MzM0NTg3NDAsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.n9AbUy1zl90Xg35aSpW-iDPQJVbEXBCDzLZxI7EVk-zdnyqnZnh--CyqIg2SGmypzSCx2H3LhA4KW6SCmlFaZj-BvEmxIpALXpgzxsA55GLf1xWB5OA7H8u94e3mx1231xqh3_GGNLjDdohp8qiuktdVoWuz3M5nNbuiTHzPAjCuwDsS1OTV9CCOX_WFpdct_7RaiOetlzeRY1Msc_MRQ3vnYYGGE4pwW57IhXM7oQAJ7ruLnzAkZ6h3bugY_c7vHKkG4gAmrBxrI0IcniXsY-DkkFQBZRyGaj-AhSNbTet7Nz-vEQOWtgo4OBmoIlcVbhPLTHt1xSuSx5pn4Fdfpg",
        "state": "CfDJ8MUXARYmDzBChfPQYArN2SH3JdRYY7x6NjAVdLn5flJFBf5lLyeOw88_tyPtFtS-0oeM80VZDjEtp1ypnpT30J8tUAJdsFONzgPtFOA7bBl3DBKIT83uyss72ZrEteN07tjGRP9YSxhE4_s3lJu83vXJCBT6ElCA055pBg_xRFaN",
        "x-client-SKU": "ID_NET",
        "x-client-ver": "2.1.4.0"
      }
    }
    
    1. 在 IDP 的 Config 中配置登出的 redirect url, 添加如下代码
                        PostLogoutRedirectUris = new List()
                        {
                            "https://localhost:44314/signout-callback-oidc"
                        },
    

    Client 端对应配置


    4-OAuth2 & OpenID Connect & Asp net core 使用IDP_第2张图片
    image.png

    这两句也可以不要,因为是默认的配置
    再次运行,注销登录会发现如下日志

    IdentityServer4.Validation.EndSessionRequestValidator:Information: End session request validation success
    {
      "ClientId": "junguoguoimagegalleryclient",
      "ClientName": "Image Gallery",
      "SubjectId": "b7539694-97e7-4dfe-84da-b4256e1ff5c7",
      "PostLogOutUri": "https://localhost:44314/signout-callback-oidc",
      "State": "CfDJ8MUXARYmDzBChfPQYArN2SHO-kKXV181UqBNd_rBw7RP_frYMPrHFlBWao7R7_IUiOv5l9zbB3PHEHSk4O74Uk9EPD2PeFQ3HMRm5DvHRTylXgMDGUKbEYag7sKpSLLyhBFWUXsYpjCujxr8ZxUvSUeyx8OzvCQzhzFpA5QEnUJ0",
      "Raw": {
        "post_logout_redirect_uri": "https://localhost:44314/signout-callback-oidc",
        "id_token_hint": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImM5ODExYjU4NDg5Yzk4Y2RlOTNlYWM2NmJmMjVhNzUzIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MzM0NTkxNTQsImV4cCI6MTUzMzQ1OTQ1NCwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMTkiLCJhdWQiOiJqdW5ndW9ndW9pbWFnZWdhbGxlcnljbGllbnQiLCJub25jZSI6IjYzNjY5MDU1OTIzNjM0Mzc2OS5PVEZpT0RZM1ltVXRNakk0TmkwME1tSTFMV0UzWm1JdE5qWmtORFpsWWpNNU5EY3paRGd5WWpBeFkyTXROV1l4TkMwME9USTFMVGt3TmprdFpEazJOamhoT1dJNE0ySTIiLCJpYXQiOjE1MzM0NTkxNTQsImF0X2hhc2giOiI2Zjdxa0ZtdFg2ZXJVa1pIRTdkTEdnIiwic2lkIjoiYjA5ZTc5Mjc2ZWYzNTE4MWJlNTk2OTkzYWM3YWMzYWQiLCJzdWIiOiJiNzUzOTY5NC05N2U3LTRkZmUtODRkYS1iNDI1NmUxZmY1YzciLCJhdXRoX3RpbWUiOjE1MzM0NTkxNTAsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.FZOb_EWRZklp9uhiWR-mLaOu0Or41rjztnwIk888t178fgFSvBn0ei_Zg3x1FuDb_0nHUXxwK_kHceCPrbNBGdmKyjpyfKDRtdX7Fnhhm91UGATlrtNG2VQs4srkwkkoj3iQUq05IhIPxBWAS3YR482WrQ3HEqe90b8cWgoN9S2OObO7d-Pjc7CH5fmDEAvkUAfC5HA4MGv3ludSJixK6Vyt3M_HyA-Wnva8m4UOWbMHcWRgZGNbFnwjYWr9oZ7wO03rlLRuZ8bmsl4sZ-oSK_YY_DUwzdxRSS1gZCwA58Xg1vITjK5XQn3nTt_0A7KmMBAjNMTRc81ckM6GvgKHtg",
        "state": "CfDJ8MUXARYmDzBChfPQYArN2SHO-kKXV181UqBNd_rBw7RP_frYMPrHFlBWao7R7_IUiOv5l9zbB3PHEHSk4O74Uk9EPD2PeFQ3HMRm5DvHRTylXgMDGUKbEYag7sKpSLLyhBFWUXsYpjCujxr8ZxUvSUeyx8OzvCQzhzFpA5QEnUJ0",
        "x-client-SKU": "ID_NET",
        "x-client-ver": "2.1.4.0"
      }
    }
    

    此时注销登录会显示一个是否跳转回 Client 配置的 redirect uri 的页面,如果要实现自动跳转
    打开 IDP 项目的 AccountOptions, 将下面的字段改为 true 即可

    public static bool AutomaticRedirectAfterSignOut = true;
    
    1. 我们配置了 options.Scope.Add("profile"); 但是查看日志并没有返回自定义的那些 Claims
      Client 端对应配置增加
      4-OAuth2 & OpenID Connect & Asp net core 使用IDP_第3张图片
      image.png

      从 IDP 的 UserInfoEndpoint 获取数据
      4-OAuth2 & OpenID Connect & Asp net core 使用IDP_第4张图片
      image.png

      可以发现也只有name相关属性被返回了,至于其他属性信息,下来的课程再讨论

    你可能感兴趣的:(4-OAuth2 & OpenID Connect & Asp net core 使用IDP)