最近的需求是要在项目中加入权限模块。在对接shrio中查找资料遇到了一些问题。所以记录下spring boot 对接 shiro 以及jwt 生成token 做权限校验。
Shiro框架中有三个核心概念:Subject ,SecurityManager和Realms。
-
Subject
Subject表示 执行当前操作的用户,当然subject 不单单指的是用户,它可以是第三方进程、定时任务,等与程序交互的东西。我们可以先给它理解为 当前操作的用户。 -
SecurityManager
SecurityManager安全管理器,是Shiro的核心。主要作用于登录、登出用创建主题Subject。它引用了多个内部嵌套安全组件,shiro本身自己调用,客户端使用应该使用Subject,而不是SecurityManager。
几乎在所有环境下,都能够获得当前执行的 Subject 通过使用 org.apache.shiro.SecurityUtils; getSubject()方法调用一个独立的应用程序,该应用程序可以返回一个在应用程序特有位置上基于用户数据的 Subject, 在服务器环境中(如,Web 应用程序),它基于与当前线程或传入的请求相关的用户数据上获得 Subject。 -
Realms
Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当与像用户帐户这类安全相关数据进行交互,执行认证(登录)和授权(访问控制)时,Shiro会从应用配置的Realm中查找很多内容。由SecurityManager来管理如何使用Realms来获取安全的身份数据
JWT
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息
开始对接
在项目对接中,我们约定了每次请求 都需要在请求头中带上token ,后端从token中取得当前登录用户的信息,进行权限校验
一般来说,数据库的权限表 分为用户表、角色表、权限表、用户角色表、角色权限表,一共五张表来实现,我们此次demo 中不进行数据库设计。假设用户 user,假设角色admin。 具体的角色、权限 可以在实际项目中验证用户时进行处理。很方便的。
首先pom文件添加依赖
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--jwt token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
两个依赖 一个是shiro依赖 一个是jwt 生成token 的依赖
我们需要给shiro 进行一个配置。 但是在在配置之前 要写一个过滤器,进行过滤请求,如果请求头里有token则交给realm 进行登录 。需要继承 shiro的 BasicHttpAuthenticationFilter,大概我们需要实现 几个方法,先从请求头取到token,如果有token,则交给 shiro 登录处理。如果没token 则表明属于游客登录,或者没权限
再者说token shiro中AuthenticationToken 用于收集用户提交的身份(如用户名)及凭据(如密码)。Shiro会调用CredentialsMatcher对象的doCredentialsMatch方法对AuthenticationInfo对象和AuthenticationToken进行匹配。匹配成功则表示主体(Subject)认证成功,否则表示认证失败
这里我们需要自定义一个token并且是shrio 认可的token 所以需要继承于 AuthenticationToken
我们先看下token,很简单的继承实现
public class JWTToken implements AuthenticationToken {
private String token;
public JWTToken(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
然后我们看一下 过滤器的实现
package com.jzdsh.demo.filter;
import com.jzdsh.demo.shiro.JWTToken;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class JWTFilter ex