zoukankan      html  css  js  c++  java
  • IdentityService4 下的 Hybird Flow 【第二章】

    对于Hybird Flow,Refresh Token还没了解的,请看第一章:https://www.cnblogs.com/hexsola1314/p/13823421.html 

    一.安装IDP

    1.为了简便,这里的IDP(授权服务器)直接使用官方提供的模板 

     安装:dotnet new -i IdentityServer4.Templates    

     正确安装完会出现下,这里我们选择的是shortName:is4inmem的模板 

     

     安装后你可能会发现IdentityServer4 4.0 对比之前不再使用ApiResource这个类,而是换成了ApiScope 我们在这里新加个api,并把这个端口设置为5001

     public static IEnumerable<ApiScope> ApiScopes =>
                new ApiScope[]
                {
                    //new ApiScope("scope1"),
                    //new ApiScope("scope2"),
                    new ApiScope("api1")//jwt            
                };

    2.新添加客户端 hybrid client

                    //mvc hybrid Client
                    new Client
                    {
                        ClientId="hybrid client",
                        ClientName="Asp.net Core hybrid",
                        ClientSecrets = {new Secret("hybrid secret".Sha256())},//因为这里要进行客户端的认证                    
                        RequirePkce = false,
                        AllowedGrantTypes = GrantTypes.Hybrid,
                        RedirectUris =
                        {
                            "http://localhost:7000/signin-oidc"
                        },
                        //登出的uri
                        PostLogoutRedirectUris =
                        {
                            "http://localhost:7000/signout-callback-oidc"
                        },
                        AllowOfflineAccess = true,  //使用refresh token
                        AccessTokenLifetime = 60, // 60 seconds  默认是1小时
                        AlwaysIncludeUserClaimsInIdToken = true,//useclaim添加到id_token里面 个人喜好  要把jwt的cliam映射给关闭
                        AllowedScopes =
                        {
                            "api1",
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile,
                            IdentityServerConstants.StandardScopes.Address,
                            IdentityServerConstants.StandardScopes.Email,
                            IdentityServerConstants.StandardScopes.Phone     
                        }
                    }

    3.由于上面scopes的变动我们需要在默认的 OpenId,Profile基础上再添加

    new IdentityResources.Address(),
    new IdentityResources.Email(),
    new IdentityResources.Phone()

    二.新建HybridClient web服务器 这里设置端口号为7000 ,为了能更好看到ids4的内置信息,我们需要安装IdentityModel这个nuget

        这里我们把jwttoken的cliam的映射给关闭,使用well-konw的简单形式

        只需要添加以下代码 

        

    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

      当然这里我们还是需要把源头指向我们的IDP,scope,cliam这里配置等等 oidc的协议,我们需要在service下添加

      

     services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                .AddCookie("Cookies", option=>
                {
                    option.AccessDeniedPath = "/Authorization/AccessDenied";
                })//身份无权限,错误跳转
                .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
                {
                    options.SignInScheme = "Cookies";
                    options.Authority = "http://localhost:5001";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "hybrid client";
                    options.ClientSecret = "hybrid secret";
                    options.SaveTokens = true;
                    options.ResponseType = "code id_token";//这里要比授权码的类型多了个id_token
                    #region Scope 范围
                    options.Scope.Clear();
                    options.Scope.Add("api1");
                    options.Scope.Add("openid");
                    options.Scope.Add("profile");
                    options.Scope.Add("email");
                    options.Scope.Add("address");
                    options.Scope.Add("phone");
                    options.Scope.Add("roles");
                    options.Scope.Add(IdentityModel.OidcConstants.StandardScopes.OfflineAccess);
                    #endregion

    #region 集合里的东西 都是要被过滤掉的属性,nbf amr exp... 需要的时候用就行了 //options.ClaimActions.Remove("nbf"); //options.ClaimActions.Remove("amr"); //options.ClaimActions.Remove("exp"); #endregion });

    别忘了在中间键加入

    app.UseAuthentication();
    app.UseAuthorization();

    和默认控制器Home中加入【Authorize】

    三.这里,我们暂时先不管api这个范围,我们把IDP和HybridClient 启动。你可能会遇到以下报错 (很坑)

      1.

      

       这个时候我们在IDP中加上这段代码 RequirePkce = false,原因是connect/authorize的参数中比Authorization Code Flow时少了一个code_challenge相关的两个参数,这个参数默认是true的,关闭即可

      2.如果你两边都使用了https来用的,就可以正常访问,因为ids4 model这个包默认是支持https的当然在官网下的例子也是采用了https,但考虑到很多人是生产环境下,没有证书,所以一般都用了http,

         但代码中也加了以下options.RequireHttpsMetadata = false; 代码还是无法正常访问,这是因为谷歌在版本5.1后加入了双重认证SameSite的认证这里我们需要把这个认证关闭就可以了,edge也是使

        用了谷歌的内核,所以我们可以输入chrome://flags/

      

      如果你没有遇到上述的问题那就是最好了,大家都省事,哈哈哈哈!

     正常启动你会得到下面的页面

     

     这里的账号和密码,你可以参考IDP下默认的两个用户alice和bob 输入后就会跳转到主页了Home/index

    四.创建一个接口作为直接和ownResouce做交互,这里需要安装identityModel的nuget包,为了简便我这里直接用官网默认的方式配置

        在service下写入以下代码  接口为6001

      

          .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "http://localhost:5001";
                    options.RequireHttpsMetadata = false;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateAudience = false
                    };
                });

    控制器IdentityController 

    [HttpGet]
            public IActionResult Get()
            {
                return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
            }

      下面我们再回到HybirdClient中,我们把请求到的accessToken 放到SetBearerToken中 再去访问接口这个时候就可以拿到api中的资源啦

      具体代码如下:

                var client = new HttpClient();
                var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");
                if (disco.IsError)
                {
                    throw new Exception();
                }
    
                var accessToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
                client.SetBearerToken(accessToken);
                var response = await client.GetAsync("http://localhost:6001/identity");
                if (!response.IsSuccessStatusCode)
                {
                     var content = await response.Content.ReadAsStringAsync();
                }

    五。为了防止文章过长下一章我们将讨论如何获取refresh Token,同时也希望上诉文章能帮到你,github开源地址会在写完后放上去

      若要转载请附上作者原文链接 https://www.cnblogs.com/hexsola1314/p/13825730.html Evan

        

      

      

  • 相关阅读:
    jmeter:dubbo接口测试
    聊聊基准测试的MVP方案
    建立团队的性能文化
    针对 Intellij IDEA 2018.2 版本 异常退出问题
    maven settings.xml配置优化
    Windows安装MySQL
    String的intern()方法详解
    Ubuntu下安装JDK图文教程详解 jdk-java6-30 .bin 的处理方法
    Iterator迭代器快捷键
    $.each $.map $.filter 区别 Script
  • 原文地址:https://www.cnblogs.com/hexsola1314/p/13825730.html
Copyright © 2011-2022 走看看