这篇文章我们来讲一下如何集成JWT到Spring Boot项目中来完成接口的权限验证。
JWT
JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
如何使用JWT?
在身份鉴定的实现中,传统方法是在服务端存储一个session,给客户端返回一个cookie,而使用JWT之后,当用户使用它的认证信息登陆系统之后,会返回给用户一个JWT,用户只需要本地保存该token(通常使用local storage,也可以使用cookie)即可。
因为用户的状态在服务端的内存中是不存储的,所以这是一种 无状态 的认证机制。服务端的保护路由将会检查请求头 Authorization 中的JWT信息,如果合法,则允许用户的行为。由于JWT是自包含的,因此减少了需要查询数据库的需要。
JWT的这些特性使得我们可以完全依赖其无状态的特性提供数据API服务,甚至是创建一个下载流服务。因为JWT并不使用Cookie的,所以你可以使用任何域名提供你的API服务而不需要担心跨域资源共享问题(CORS)。
大概就是这样:
Spring Boot集成
我是勤劳的搬运工,这应该是翻译老外的东西,项目地址:https://github.com/thomas-kendall/trivia-microservices。
废话不多说了,我直接上代码,依然是搬运工。
我是gradle构建的,就是引入一些依赖的jar包。顺便推荐一下阿里云的中央仓库
http://maven.aliyun.com/nexus/content/groups/public/
|
|
下面这个是类是产生token的主要类
|
|
现在我们需要一个定制授权过滤器,将能读取请求头部信息,在Spring中已经有一个这样的授权Filter称为:RequestHeaderAuthenticationFilter,我们只要扩展继承即可:
|
|
在这里,头部信息将被转换为Spring Authentication对象,名称为PreAuthenticatedAuthenticationToken
我们需要一个授权提供者读取这个记号,然后验证它,然后转换为我们自己的定制授权对象,就是把header里的token转化成我们自己的授权对象。然后把解析之后的对象返回给Spring Security,这里就相当于完成了token->session的转换。
|
|
Spring Security
上面完成了JWT和Spring Boot的集成。
接下来我们再如何把自己的权限系统也接入Spring Security。
刚才已经展示了通过JsonWebTokenAuthenticationProvider的处理,我们已经能通过header的token来识别用户,并拿到他的角色和userId等信息。
配置Spring Security有3个不可缺的类。
首先配置拦截器,拦截所有的请求。
|
|
然后是把我们自己的权限数据加载到Spring Security中。
|
|
现在我们拿到了用户的角色,也拿到了系统里有的角色和权限,就需要判断他是否有这个权限了,配置如下:
|
|
我们试试登录的接口:
然后我们用这个token来调用另外一个接口。
我们先试试不传Token会返回什么
判断没有登录,现在再来试试带上token的请求。
已经成功的请求到了数据。
好了,核心配置就是这些,我把这些代码上传github上,有需要的可以下载下来看看。里面的角色和权限都是虚拟数据,应用还需要自行修改代码。
https://github.com/sail-y/spring-boot-jwt