zoukankan      html  css  js  c++  java
  • asp.net core IdentityServer4 实现 resource owner password credentials(密码凭证)

    前言

    OAuth 2.0默认四种授权模式(GrantType)

    本章主要介绍密码模式(resource owner password credentials),OAuth2.0资源所有者密码授权功能允许客户端将用户名和密码发送到令牌服务,并获得该用户的访问令牌.

    认证步骤:

    • 用户将用户名密码提供给客户端
    • 客户端再将用户名密码发送给授权服务器,请求令牌
    • 授权服务器确定判断信息是否有误,返回给客户端令牌

    创建授权服务器

    创建一个API项目工程,我这边以端口5000的形式进行后面的讲解.

    Package

    PM> Install-package IdentityServer4 -version 2.5.3

    创建一个类Config(配置要保护的资源,和可以访问的API的客户端服务器)

       public class Config
        {
            /// <summary>
            ///     定义要保护的资源
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<ApiResource> GetApiResources() {
                return new List<ApiResource>
                {
                   new ApiResource("api1","MyApi")
                };
            }
            /// <summary>
            ///     定义授权客户端
            /// </summary>
            /// <returns></returns>
            public static IEnumerable<Client> GetClients() {
                return new List<Client>
                {
                    new Client(){ 
                        ClientId="client",
                        AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,
                        ClientSecrets=
                        {
                          new Secret("secret".Sha256())
                        },
                        AllowedScopes={ "api1",IdentityServerConstants.StandardScopes.OfflineAccess //如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess
                        },
                        AllowOfflineAccess=true// 主要刷新refresh_token,
            
                    }
                };
            }
        }
    
    

    此处AllowedGrantTypes需要设置为ResourceOwnerPassword(密码凭证).

    配置Startup

    再走到ConfigureServices方法注入IdentityServer4服务

       public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
                services.AddIdentityServer()
                    .AddDeveloperSigningCredential()
                    .AddInMemoryApiResources(Config.GetApiResources())
                    .AddInMemoryClients(Config.GetClients())
                    .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();//注入自定义登录验证
    
            }
    
    

    IdentityServer4默认提供了两种证书加密配置
    AddDeveloperSigningCredential AddTemporarySigningCredential
    添加内存ApiResourceAddInMemoryApiResources
    添加内存Client AddInMemoryClients
    添加自定义登录验证AddResourceOwnerValidator

    自定义用户验证
        public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
        {
            public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
            {
                if (context.UserName == "test" && context.Password == "test")
                {
                    context.Result = new GrantValidationResult(
                     subject: context.UserName,
                     authenticationMethod: OidcConstants.AuthenticationMethods.Password);
                }
                else
                {
                    //验证失败
                    context.Result = new GrantValidationResult(
                        TokenRequestErrors.InvalidGrant,
                        "invalid custom credential"
                        );
                }
                return Task.FromResult(0);
            }
        }
    
    

    在Configure方法中添加IdentityServer4服务中间件

    app.UseIdentityServer();

    创建ApiResource

    创建一个客户端项目,这边我将端口设置为5001

    Package

    PM> Install-package IdentityServer4 -version 2.5.3

    配置Startup

    在ConfigureServices添加认证服务器地址

          public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
                services.AddAuthentication("Bearer")
                  .AddIdentityServerAuthentication(options =>
                  {
                      options.Authority = "http://localhost:5000";//授权服务器地址
                       options.RequireHttpsMetadata = false;//不需要https    
                       options.ApiName = "api1";
                  });
            }
    

    在Configure方法中添加认证服务中间件

    app.UseAuthentication();

    Run

    在客户端程序values控制器上面增加[Authorize]

    直接访问资源服务器http://localhost:5001/api/values

    code 401

    启动授权服务器

    http://localhost:5000/.well-known/openid-configuration

    发现端点可通过/.well-known/openid-configuration

    获取token

    这边我用postman进行测试

    code 200

    access_token我们获取到了,再拿着token通过postman请求资源程序,

    code 200
    成功了

    refresh_token

    获取请求授权接口后会返回access_token expires
    _in 等内容,expires_in是有效期(s),当然我们可以自定义有效期,access_token失效后用户需要重新授权,client才能拿到新的access_token.但是有了refresh_token后,client检测到token失效后可以直接通过refresh_token向授权服务器申请新的token,当然refresh_token也是有有效期的。
    AbsoluteRefreshTokenLifetime的默认有效期为2592000秒/30天。SlidingRefreshTokenLifetime的默认有效期为1296000秒/15天。

    在认证服务器中我再scopes加上了OfflineAccess
    IdentityServerConstants.StandardScopes.OfflineAccess //如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess

    获取refresh_token

    通过refresh_token再去获取access_token

    通过postman请求获取资源

    概要

    示例地址https://github.com/fhcodegit/IdentityServer4.Samples

  • 相关阅读:
    mod_rewrite
    敏捷开发
    转python和ruby的相同点
    ESB总线知识小结
    使用 squid 2.7 for windows 进行无缓存反向代理
    初探K2workflow
    没激情的工作
    多易拍 二次开发
    查看数二进制代码片段
    生成随机数
  • 原文地址:https://www.cnblogs.com/yyfh/p/11601903.html
Copyright © 2011-2022 走看看