前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >asp.net core IdentityServer4 实现 resource owner password credentials(密码凭证)

asp.net core IdentityServer4 实现 resource owner password credentials(密码凭证)

原创
作者头像
HueiFeng
修改2020-02-12 14:46:17
1.3K0
修改2020-02-12 14:46:17
举报
文章被收录于专栏:HueiFeng技术专栏HueiFeng技术专栏

前言

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

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

认证步骤:

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

创建授权服务器

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

Package

`

PM> Install-package IdentityServer4 -version 2.5.3

`

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

代码语言:txt
复制
   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服务

代码语言:txt
复制
   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

自定义用户验证
代码语言:txt
复制
    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添加认证服务器地址

代码语言:txt
复制
      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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Package
  • 配置Startup
  • 自定义用户验证
  • Package
  • 配置Startup
  • 启动授权服务器
  • 获取token
  • 获取refresh_token
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档