前言

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

最新文章

  1. Sqoop2中传入配置文件中url之【坑】
  2. LoadRunner之篇
  3. 在Mysql中Using filesort代表什么意思?
  4. ios取证
  5. 【题解】【矩阵】【回溯】【Leetcode】Unique Paths II
  6. Java 中无参带返回值方法的使用
  7. Delphi XE5教程12:注释和编译器指示字
  8. 8个月从CS菜鸟到拿到Google Offer的经历+内推
  9. DirectShow系统初级指南
  10. JS 格式化日期
  11. python的内存管理机制 图解+Django Web开发学习笔记
  12. 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)
  13. 让你的MyEclipse具有jquery自动提示
  14. ajax跨域问题及解决
  15. How to speed up Remote Desktop Connection in Win7
  16. 你不知道的JavaScript--Item14 使用prototype的几点注意事项
  17. java mongodb的MongoOptions生产级配置
  18. JAVA核心技术I---JAVA基础知识(类的继承)
  19. Canvas绘图优化之使用位图--基于createjs库
  20. Python学习笔记第六周

热门文章

  1. 使用Python的Django和layim实现即时通讯
  2. 通过类来实现多session 运行
  3. Python学习 之三 Python基础&amp;运算符
  4. python批量处理压缩文件
  5. 搭建Spark高可用集群
  6. Python字典排序问题
  7. codeforces E. Phone Talks(dp)
  8. c++11特性学习总结
  9. 《2019面向对象程序设计(java)课程学习进度条》
  10. 【Offer】[25] 【合并两个排序的链表】