然鹅,在springcloud中,各个微服务直接暴露的是restful接口丛友,此时如何让各个微服务获取到当前用户信息呢?最佳的方式就是token了,token作为BS之间的会话标识(一般是原生随机token),同时也可以作为信息的载体传递一些自定义信息(jwt, 即Json web token)。
为了能更清楚的了解本文,需要对spring-security-oauth 及 jwt有一定了解,本文只关注用户信息传递这一块
认证服务器配置 AuthorizationServerConfigurerAdapter
自定义token转换器
CustomJwtAccessTokenConverter
此时按照固定格式访问授权服务器token接口获取token,如图,可以获取到jwt格式的token,并且额外信息nick_name也已经添加
直接解析jwt字符串可以获取到以下信息,即用户名和授权信息
只需要指定和授权服务器一模一样的token store 和token converter
在securiy的过滤器中 OAuth2AuthenticationProcessingFilter 会从token中获取相关信息进行鉴权
源码:
注意,资源服务器主要配置在
ResourceServerConfigurerAdapter
微服务获取jwttoken中的用户信息,两种方式,使用security上下文可以直接获取当前用户名和权限,另一种自定义拦截器获取额外信息。
这个就简单了,获取header头解析验证token
然后获取之前从授权服务器中的添加的 nick_name的额外信息放入线程变量
其中用户上下文类
启动拦截器注册webmvc配置类
在controller中获取用户信息如图
在默认的认证异常如图
假设我们做了全局异常处理,前端希望在token过期时做统一的登录跳转如何做?
实现 AuthenticationEntryPoint 接口重写 commence 方法即可
注意,直接抛出异常并不会走 @RestControllerAdvice , 因为在这里是response直接返回,并没有使用到Controller处理
此时返回我自定义的Response对象,如图
JWT由三部分组成,由类型和加密算法的head(头部),包含公共信息和自定义信息的playboard(负载),以及signature(签名)组成。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 就是头部信息,这是由base64加密后的密文,base64是一种对称加密算法,解密后的json格式如下。头部信息由type(类型)和 alg(加密算法)组成。类型就是"JWT",加密算法一般使用 HMAC SHA256加密算法。
eyJhdWQiOiIzOTU4MTU4MDEiLCJleHAiOjE2MDYxMDc5NTEsImlhdCI6MTYwNjEwMDc1MX0 就是负载信息,加密后神升知的json格式如下。负载信息一般由标准申明,公共声明,私有声明组成。
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间笑竖必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
公共的声明和私有的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息。但不建议添加敏感信息,因为该部分在客户端可解密。
第三部分签名是由base64加密后的头部信息和负载信息以及secret组成的签名,签名算法是游消有头部信息定以的加密算法,一般是HMAC SHA256。然后头部,负载,签名三部分组成了token。
pom.xml引入依赖
新增controller,提供token接口
CallbackService 生成token
返回的示例如下
定义自定义注解,在需要token校验的方法上加上即可
新增AuthenticationInterceptor对第三方请求进行拦截,实现HandlerInterceptor接口
注册AuthenticationInterceptor拦截器,对指定请求路径进行拦截
在此文中,我们大致了解了Token的定义,获取,校验等方法。此外,Token 的无状态,可扩展性,多平台跨域等特性,也让Token广泛应用在安全校验领域中。在接下来的几篇文章中,我将介绍如何使用Spring AOP进行加密,解密,验签等 *** 作。
参考:
https://www.jianshu.com/p/576dbf44b2ae
一个JWT由三部分组成:
Header(头部) —— base64编码的Json字符串
Payload(载荷) —— base64编码的Json字符串
Signature(签名)—— 使用指定算法,通过Header和Payload加盐计算的字符串
各部分以" . "分割,如:
直接通过base64解码可获得
Header:
Payload:
本文基于:
Jwts.builder() 返回了一个 DefaultJwtBuilder()
DefaultJwtBuilder属性
DefaultJwtBuilder包含了一些Header和Payload的一些常用设置方法
如空磨册果即不设置签名,也不进行压缩,header是不是就应该没有了呢?
不是。即时游明不进行签名,alg也应该存在,不然对其进行解析会出错。
在生成jwt的时候,如果不设置签名,那么header中的alg应该为none。jjwt中compact()方法实现如下:
即
还提供了 JWT标准 7个保留声明(Reserved claims)的设置方法,7个声明都是可选的,也就是说可以不用设置。
Payload 举例:
当然也可以在Payload中添加一些自定义的属性claims键值对
jjwt实现的 DefaultJwtSigner 提供了一个带工厂参斗宏数的构造方法。并将jjwt实现的 DefaultSignerFactory
静态实例传入,根据不同的签名算法创建对应的签名器进行签名。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)