IdentityServer4实战 - AccessToken 生命周期分析
一.前言
IdentityServer4实战这个系列主要介绍一些在IdentityServer4(后文称:ids4),在实际使用过程中容易出现的问题,以及使用技巧,不定期更新,谢谢大家关注。使用过ids4的朋友应该知道,可以通过设置AccessTokenLifetime
属性,来控制AccessToken的存活时间,但是细心的朋友可能会发现,Token到期了依然能通过授权,这是怎么回事呢,下面我带大家一起来揭开神秘面纱。
二.关于 ID Token 和 AccessToken
Openid Connect(后文称:OIDC)是在OAuth2.0协议上进行了扩展,OIDC=Identity+OAuth2.0,使其拥有身份认证+授权的能。它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。我们都知道OAuth2是一个授权协议,它无法提供完善的身份认证功能,OIDC使用OAuth2的授权服务器来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且可以适用于各种类型的客户端(比如服务端应用,移动APP,JS应用),且完全兼容OAuth2,也就是说你搭建了一个OIDC的服务后,也可以当作一个OAuth2的服务来用。应用场景如图:
OAuth2提供了Access Token来解决授权第三方客户端访问受保护资源的问题;OIDC在这个基础上提供了ID Token来解决第三方客户端标识用户身份认证的问题。OIDC的核心在于在OAuth2的授权流程中,一并提供用户的身份认证信息(ID Token)给到第三方客户端,ID Token使用JWT格式来包装,得益于JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID Token可以安全的传递给第三方客户端程序并且容易被验证。此外还提供了UserInfo的接口,用户获取用户的更完整的信息。
简而言之ID Token就是JWT格式的数据,包含一个人类用户的身份认证的信息,一个ID Token的例子如下:
{
"iss": "https://server.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"auth_time": 1311280969,
"acr": "urn:mace:incommon:iap:silver"
}
看到上面的数据是不是感觉很熟悉,这是一个我们从ids4申请的"AccessToken":
eyJhbGciOiJSUzI1NiIsImtpZCI6IjhlM2U2MWY1ZWUyZDgwMGNlYjE2NmE5NGRjODczMTY0IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MjU1Nzg3MTUsImV4cCI6MTUyNTU3ODcxNiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9yZXNvdXJjZXMiLCJhcGkxIl0sImNsaWVudF9pZCI6InJvLmNsaWVudCIsInN1YiI6IjEiLCJhdXRoX3RpbWUiOjE1MjU1Nzg3MTUsImlkcCI6ImxvY2FsIiwic2NvcGUiOlsiYXBpMSJdLCJhbXIiOlsicHdkIl19.JXU4bXUqf8QD4zQz61XC2WTKURtNIVhH23zQPJzOmEtYbQvO2oRP58sCfDQxADeImZ7O0vH4YXIfL8j60B-sAYJev7c2hnjVhHTJ0t-0bUPlLs43cqNG6RarZ8FyfHyhrvIwYBpJXKNROfr6GfLb4Vdpw4ZEd4AC2k2tHuKMfyrrTzqS0oUs1RwqH7KZ1W7pXDr_V2L4PjgCqOQelXAB_V5YXzR9E52FIXnKNzCVnWHmhiTSWg-ptONOoHss1a-ElWejXskTlMBQitnxSno05s4O6vp5R8zqMuo3j57SnPZVaTuR4AUVpDdVmFF9x9k-fHuXyqarsW6YGsXgTTA2Lw
我们将上面的Token解码可以看见:
我想不用我多说,就可以看见我们的ID Token在哪里吧。
三.设置AccessToken过期时间
我们在ids端设置我们的客户端资源的时候有一个AccessTokenLifetime
属性,此属性可以设置我们申请的Token的有效时间,单位是秒,默认3600秒也就是一个小时。
代码示例:
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AccessTokenLifetime = 5,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
}
本文所用代码,为ids4文档中,第二个QuickStart,文末会给出地址。
Client对象还包含一个
IdentityTokenLifetime
属性,是用来设置ID Token的存活时间,但是,我们获得AccessToken以后,访问API资源等,是用的授权,此属性无法影响AccessToken的有效期,这也是我在上面解释了ID Token和AccessToken的区别的原因,希望大家不要搞混淆了。
我们上面将AccessToken的存活时间设置为5s,我们修改客户端的代码改一下,让他暂停6s再次去访问APi资源,看看会发生什么:
我们先看看返回的AccessToken信息里,过期时间已经变成了5s:
看看暂停之后的结果:
可以看到,本来Token应该过期无法访问的,但是还是成功访问API获取到了信息:
这是怎么回事呢,和我们想的有点不一样,请听下节分解!
四.时间偏移(ClockSkew )
有这样的场景,如果你的AccessToken还有5s过期,这时你通过这个AccessToken去访问API资源,但是这时网络堵塞,可能请求10s才到达目标,那这时怎么办?如果需要保持所持有的AccessToken一直有效,是否需要提前刷新或者再次申请AccessToken?如果你本地的时间和API资源服务的时间具有时间差异可能是几秒,几十秒等等,那么你该如何判断你所持有的AccessToken的有效性?
上述的这些问题,都是我们将时间理想化了,所以当我们的API资源受到请求根据AccessToken进行验证的时候,会有一个时间偏移,通俗的讲就是将AccessToken的逻辑过期时间往后推迟了,这个时间默认是5分钟。比如我们的AccessToken应该在2018年5月6日16:50:55
过期,那么实际上在API资源进行验证的时候,容忍在过期时间后的五分钟以内,此AccessToken依然是有效的,即在API资源验证时,此AccessToken的真正过期时间为2018年5月6日16:55:55
,这个时间差就是用来解决上述问题的。这也是为什么上面我们将AccessToken设置5s过期,但实际上5s之后还能用它成功访问API。
此设置是针对于JWT的,这里需要注意。
五.设置时间偏移
1.获取默认过期时间
默认过期时间我们可以通过JwtBearerOptions
对象的TokenValidationParameters
属性的ClockSkew
属性来获取。
可以看见默认的时间偏移为5分钟,那么如何来自定义这个值呢。
2.设置时间偏移
我们可以通过IdentityServerAuthenticationOptions
对象提供JwtValidationClockSkew
属性来自定义时间偏移,这个设置是在API资源的,因为当我们请求API资源的时候,是API资源自行进行验证的。
代码如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.JwtValidationClockSkew = TimeSpan.FromSeconds(0);
options.ApiName = "api1";
});
}
我们通过options.JwtValidationClockSkew = TimeSpan.FromSeconds(0);
将这个时间偏移设置为了0s,那么我们现在再运行我们前面的程序,设置AccessToken过期时间为5s,我们暂停6s,会发生什么。
可以看到提示“Unauthorized”,可以看到现在的情况和我们前面所想的情况一致了。这就是时间偏移的作用。
六.写在最后
在实际生产环境中,一定要尽量保持各个服务,各个节点的时间同步,使用标准时间。然后这个时间偏移如没有特殊需求不建议去更改它,这个就是这样设计的,官方也是不推荐去更改它。如果设置过短可能引起文章说的问题哦。欢迎大家加入QQ群(4656606)和我一起交流,写本文也是群里许多朋友问过这个问题,以前一直没注意,今天才算解开了它的秘密。
本文所用代码下载:
https://github.com/stulzq/IdentityServer4.Samples/tree/master/Practice/02_AccessTokenLifetime
参考资料:
IdentityServer4实战 - AccessToken 生命周期分析的更多相关文章
- Fragment(四)Fragment生命周期分析(转)
Fragment(四)Fragment生命周期分析 转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/24271607 例子一 ...
- 12、Cocos2dx 3.0游戏开发找小三之3.0中的生命周期分析
重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27706303 生命周期分析 在前面文章中我们执行了第 ...
- Django(35)Django请求生命周期分析(超详细)
Django请求生命周期分析 1.客户端发送请求 在浏览器输入url地址,例如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都 ...
- Django(47)drf请求生命周期分析
前言 一般我们写完序列化以后,我们就会开始写视图了,drf中我们一般使用CBV的方式,也就是类视图的方式,最基础的我们会使用from rest_framework.views import API ...
- Android 中Activity生命周期分析(二):从AActivity 到BActivity过程分析
如果你没有动手去演示的话,你一定要去动手试试看,这个东西非学容易出错,面试中经常出现,好了,上代码: package com.king.review.base; import android.app. ...
- Spring Boot 启动源码解析结合Spring Bean生命周期分析
转载请注明出处: 1.SpringBoot 源码执行流程图 2. 创建SpringApplication 应用,在构造函数中推断启动应用类型,并进行spring boot自动装配 public sta ...
- ViewController的生命周期分析和使用
iOS的SDK中提供很多原生ViewController,大大提高了我们的开发效率,下面是我的一些经验. 一.结构 按结构可以对iOS的所有ViewController分成两类:1.主要用于展示内容的 ...
- iOS控制器的生命周期分析和使用
转自http://blog.csdn.net/qijianli/article/details/7826979 iOS的SDK中提供很多原生ViewController,大大提高了我们的开发效率,下面 ...
- [zhang] ViewController的生命周期分析和使用
iOS的SDK中提供很多原生ViewController,大大提高了我们的开发效率,下面是我的一些经验. 一.结构 按结构可以对iOS的所有ViewController分成两类:1.主要用于展示内容的 ...
随机推荐
- iOS动画进阶 - 教你写 Slack 的 Loading 动画
(转载自:http://blog.csdn.net/wang631106979/article/details/52473985) 如果移动端访问不佳,可以访问我的个人博客 前几天看了一篇关于动画的博 ...
- Linux下使用两个线程协作完成一个任务的简易实现
刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务. 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的 ...
- Java与C之间的socket通信
最近正在开发一个基于指纹的音乐检索应用,算法部分已经完成,所以尝试做一个Android App.Android与服务器通信通常采用HTTP通信方式和Socket通信方式.由于对web服务器编程了解较少 ...
- mac 下终端 操作svn命令 以及出现证书错误的处理方法
首先,转载地址:http://hi.baidu.com/zhu410289616/item/eaaf160f60eb0dc62f4c6b0e 还有一个地址:http://www.cnblogs.com ...
- 5个你不知道的HTML5的接口
原文地址:5 HTML5 APIs You Didn't Know Existed 原文日期: 2010年09月27日 翻译日期: 2013年8月7日 当人们看到或者说出"HTML5&quo ...
- RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇 ...
- 【Unity Shaders】Reflecting Your World —— Unity3D中的遮罩反射(Masking Reflections)
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 数据拟合:多项式拟合polynomial curve fitting
http://blog.csdn.net/pipisorry/article/details/49804441 常见的曲线拟合方法 1.使偏差绝对值之和最小 2.使偏差绝对值最大的最小 3 ...
- LCD正向扫描和反向扫描
LCD正向扫描和反向扫描 LCD扫描一般分正向扫面和反向扫描,分别针对正装和倒装结构(如下): 有时候提到长边扫描和短边扫描应该是针对横屏和竖屏的设置,大部分显示屏是正向扫描,是否都支持,和玻璃有关, ...
- UIActionSheet,UIAlertView技术分享
UIActionSheet #import "FirstViewController.h" @interface FirstViewController ()<UIActio ...