Springboot security oauth2 jwt实现权限控制,实现微服务获取当前用户信息

Springboot security oauth2 jwt实现权限控制,实现微服务获取当前用户信息,第1张

在原先dubbo+zookeeper项目中,web模块只暴露Restful接口,各服务模块只暴露duboo接口,此时用户登录后由web项目进行token的鉴权和验证,并通过dubbo的隐式传参将sessionID传递给dubbo服务模块, 拦截器再根据sessionID从Redis中获取用户信息设置到当前线程

然鹅,在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对象,如图

一、token在header中的传输规范

二、uuid在header中的传输规范

三、防重放攻击传输规范:

四、权限校验失败返回值

>

常见的鉴权方式有两种,一种是基于session,另一种是基于token方式的鉴权,我们来浅谈一下两种 鉴权方式的区别。

session

token

业界常用的授权标准有两种,一种是使用auth2,这种方式更适合于类似第三方授权登录,比如微信、微博、QQ信任登录业务。另一种是oauth,即第三方无需知道用户和密码就可以申请获得该资源的授权,更适用于对用户的权限校验并分配访问权限,比如常见的登录后分配可见资源(按钮、菜单等)类型网站。

Javashop电商系统 采用的是oauth方式的鉴权标准。我们以系统的应用为例来介绍oauth的方案。

1 登录

服务端校验密码,成功后返回access_token和refresh_token,客户端记录上述token。

2 访问API

在访问API之前解析access_token,并且查看是否过期,如果不过 期则请求API,如果过期,则要刷新令牌,在请求API。

3 刷新token

携带有效期的refresh_token换回有效token,如果refresh_token过期,则需要用户重新登录。

4 注销

请求注销api,服务器端和客户端应同时删除token的存储。

1 客户端请求API

携带access_token信息,如果生成环境不会直接携带access_token,会使用加密后的签名校验。祥见以下防重放机制。

2 获取token

根据环境不同而有不同的获取token方式。

3 解析token

通过JWT工具将token解析。

4 由redis读取token

根据uid拼接key读取access_token, 如果不存在这个用户的token说明已经登出。

5 验证token

判断次token是否属于此uid,判断token是否过期,如果过期则进行以下刷新token的流程。

6 注入权限

如果token验证成功,根据user信息生成权限注入到spring安全上下文中。

1 客户端请求API

携带refresh_token,如果是生产环境不会直接携带refresh_token信息,详见以下防重放攻击。

2 获取token

根据环境不同而有不同的获取token方式。

3 解析token

通过JWT工具将token解析。

4 token读取

根据uid拼接key读取出access_token,如果不存在这个用户的token说明用户已经登出。

5 验证token

判断此token是否属于此uid,判断token是否已经过期,如果过期,则返回refresh_token过期错误,此时用户需要重新登录。

6 刷新token

如果refresh_token 验证成功,则重新生成access_token和refresh_token,上述有效期以当前时间向后计算,替换此用户在redis中的token,并将token返回给客户端。

一、 参数的读取

1 在生产环境时,不能直接传递token,而是要传递签名数据,服务器端验签后由Redis中获取签名。

2 如果是非生产环境,直接由header中读取token。

二、 生产环境传递如下参数

memberid (用户id)

nonce(随机字串,6位)

timestamp(当前时间戳,到秒)

sign= md5( uid+ nonce + timestamp +token )

三、 验证逻辑

1 验证时间戳

判断时间戳是否起过60s,大于60s则判别为重放功击。

2 验证nonce

首先验证nonce在 reids中是否存在,如果存在,则判别为重放功击,否则将nonce记录在redis中(key为:"nonce"+uid+"_"+nonce),失效时间为60s。

3 验证sign

md5( uid+ nonce + timestamp +token ) 验证是签名是否通过。

4 验证token

通过uid拿到token ,验证逻辑同验权流程。

当然在不同的业务场景下实现方案是多种多样的,仅以此方案抛转引玉,供大家参考。

token已经放到authorization了还是不行的原因是无法按照规则生成token。本地登录时,没有携带token,直接跳转了。线上访问时,携带token,但是是无效的,就给你了个提示。这种情况,需要有前端逻辑来控制跳转。

解决token无效的方法:

1、需要授权的API,必须在请求头中使用Authorization字段提供token令牌。

2、用户授予第三方应用访问该用户某些资源的权限,在安装手机应用的时候,APP会询问是否允许授予权限访问相册、地理位置等权限。

3、在访问微信小程序时,当登录时,小程序会询问是否允许授予权限获取昵称、头像、地区、性别等个人信息。实现授权的方式有:cookie、session、token、OAuth。

4、需要在mainjs文件里添加axios拦截器然后在请求头中可以发现Authorization的值还是Null,原因就是当你发送的发出的是登录请求,在登录期间服务器没有给你token,如果登录之后调用其他接口再去监听这次请求的话就会发现Authorization的值不再是null了,而是登录后的token。

5、根据授权Authorization的解释,之所以要这么做的原因就是要给token授权访问api接口的权限。

百度百科-Token

以上就是关于Springboot security oauth2 jwt实现权限控制,实现微服务获取当前用户信息全部的内容,包括:Springboot security oauth2 jwt实现权限控制,实现微服务获取当前用户信息、JWT【分布式鉴权方案】、基于token机制鉴权架构等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9454135.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存