Loading

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

    

  

  

posted @ 2020-10-17 10:51  Evan-Huang  阅读(296)  评论(0编辑  收藏  举报