springboot使用jwt进行权限验证
springboot使用jwt进行权限验证
依赖准备
首先导入对应的依赖
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
</dependencies>
这里需要用到一些工具类来方便我们进行操作

工具类中默认的数据封装对应的user只有两个属性,即用户名、密码,一般也不需要进行修改。
属性配置
对于信息的加密解密,我们需要有公钥和私钥,在application.yml中我们需要定义配置信息。
tens:
jwt:
secret: leyou@Login(Auth}*^31)&heiMa%
pubKeyPath: G:\\tensquare\\rsa\\rsa.pub
priKeyPath: G:\\tensquare\\rsa\\rsa.pri
expire: 30
cookieName: TQ_TOKEN
cookieMaxAge: 30
注意格式,以及目录不要使用中文路径,还有在IDEA的编码属性没设置好的话不要使用中文注解,不然都会报错!
接下来自然是在属性类中加载这些数据了
@ConfigurationProperties(prefix = "tens.jwt")
public class JwtProperties {
private String secret;
private String pubkeyPath;
private String prikeyPath;
private int expire;
private PublicKey publicKey;
private PrivateKey privateKey;
private String cookieName;
private Integer cookieMaxAge;
private static final Logger logger = LoggerFactory.getLogger(JwtProperties.class);
/**
* @PostContruct: 在构造方法执行后执行该方法
*/
@PostConstruct
public void init(){
try{
File pubkey = new File(pubkeyPath);
File prikey = new File(prikeyPath);
if(!pubkey.exists() || !prikey.exists()){
//如果没有密钥文件的话,就生成公钥和私钥
RsaUtils.generateKey(pubkeyPath,prikeyPath,secret);
}
//获取公钥私钥
this.publicKey = RsaUtils.getPublicKey(pubkeyPath);
this.privateKey = RsaUtils.getPrivateKey(prikeyPath);
}catch (Exception e){
logger.error("初始化公钥私钥失败!",e);
throw new RuntimeException();
}
}
}
这里省略了getter、setter,记得要写,不然数据加载会出错。还有配置文件的前缀要写对。这里并没有使用@Compenent这种方式将配置类加载到spring容器里去。而是选择了在需要使用配置类的地方加上@EnableConfigurationProperties({JwtProperties.class})注解。
登录验证
接下来我们就可以将登陆方法修改成先进行数据库验证,如果验证成功就利用jwt来生成对应的token以及公钥密钥,再将token放入cookie,这样用户进行其他操作的时候我们就可以进行状态以及权限判断了。
AuthController下的登录验证方法
@PostMapping("accredit")
public Result authentication(@RequestParam("username")String username,
@RequestParam("password")String password,
HttpServletRequest request, HttpServletResponse response){
//首先进行登录验证,即先判断账号密码是否正确,不正确的话直接返回失败信息,正确的话就把token写入cookie
String token = this.authService.authentication(username,password);
System.out.println(prop);
if(StringUtils.isBlank(token)){//即用户名或者密码错误,没有成功获取token
return new Result(false, StatusCode.ERROR,"登录失败");
}
//将token写入cookie,并指定HttpOnly为true,防止前端通过js进行修改
CookieUtils.setCookie(request,response,prop.getCookieName(),token,prop.getCookieMaxAge(),null,true);
return new Result(true,StatusCode.OK,"登录验证成功");
}
接下来就该写验证的service了。
AuthService
@Service
public class AuthService {
@Autowired
private UserDao userDao;
@Autowired
private JwtProperties properties;
public String authentication(String username, String password) {
try{
UserInfo userInfo = new UserInfo();
userInfo.setUsername(username);
userInfo.setPassword(password);
UserInfo user = this.userDao.selectOne(userInfo);
if (user ==null){
return null;
}
String token = JwtUtils.generateToken(new UserInfo(user.getId(),user.getUsername()),
properties.getPrivateKey(), properties.getExpire());
return token;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
这便是从登陆验证到生成token的过程了。初次登录后在token有效的时间内,我们都不是直接接收前端传来的username、password来判断用户了,而是直接获取token来检验,当然,token不一定非要放在cookie里,前端也可以每次请求的时候把token传过来。
那么这里就需要一个检验用户的接口,用以将token转化为用户信息。
用户检验
用户检验接口
/**
* 验证用户信息
* @param token
* @return
*/
@GetMapping("verify")
public Result verifyUser(@CookieValue("LY_TOKEN")String token){
try {
// 从token中解析token信息
UserInfo userInfo = JwtUtils.getInfoFromToken(token, this.prop.getPublicKey());
// 解析成功返回用户信息
return new Result(true,StatusCode.OK,"",userInfo);
} catch (Exception e) {
e.printStackTrace();
}
// 出现异常则,响应错误
return new Result(false,StatusCode.ERROR,"");
}
刷新token
配置文件中写的token有效时间是30分钟,但是用户有可能一直在线,因此应该加上刷新token的机制,即再某个节点又重新覆盖一遍token。
前端对很多地方的操作都需要获取用户信息,因此我们在用户检验接口那里增加一个刷新操作。
/**
* 验证用户信息
* @param token
* @return
*/
@GetMapping("verify")
public Result verifyUser(@CookieValue("LY_TOKEN")String token,HttpServletRequest request, HttpServletResponse response){
try {
// 从token中解析token信息
UserInfo userInfo = JwtUtils.getInfoFromToken(token, this.prop.getPublicKey());
// 解析成功要重新刷新token
token = JwtUtils.generateToken(userInfo, this.prop.getPrivateKey(), this.prop.getExpire());
// 更新cookie中的token
CookieUtils.setCookie(request, response, this.prop.getCookieName(), token, this.prop.getCookieMaxAge());
// 解析成功返回用户信息
return new Result(true,StatusCode.OK,"",userInfo);
} catch (Exception e) {
e.printStackTrace();
}
// 出现异常则,响应错误
return new Result(false,StatusCode.ERROR,"");
}
很多时候我们从token中获取用户信息只是前端的请求中的一部分需求,因此上述逻辑感觉封装在一个service里面的用处更大。
利用拦截器进行权限检验
很多时候我们不会专门去对每一个请求接口都加上这么一个用户信息检验这样的逻辑,那么这里我们就需要配置一个拦截器来对请求进行拦截。通过判断token来判断该请求是否是在登录状态发起的,如果不是登录状态,那就转发到登录界面让其登录。
拦截器:
通过实现springmvc的HandlerInterceptor接口来声明一个拦截器
@EnableConfigurationProperties(JwtProperties.class)
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private JwtProperties properties;
@Override
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) throws IOException {
String token = CookieUtils.getCookieValue(request, properties.getCookieName());
// 校验
try {
// 校验通过什么都不做,即放行
JwtUtils.getInfoFromToken(token, this.properties.getPublicKey());
} catch (Exception e) {
// 校验出现异常,返回403
response.sendRedirect("/auth/accredit");
return false;
}
return true;
}
/**
* 在请求被处理后,视图渲染之前调用
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 在整个请求结束后调用
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
注意照理来说我们就应该在这里加上一个@Component注解才对,这样在springmvc的配置类那里我们也可以直接调用来注册,但是现实告诉我那样会报错,会导致我们的资源文件JwtProperties加载不到我们在yml中的数据,然而controller中的数据依旧是能读取到的。
注册拦截器以及声明白名单:
先来了解一下WebMvcConfigurer这个接口
WebMvcConfigurer配置类其实是Spring内部的一种配置方式
采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制
基于java-based方式的spring mvc配置
需要创建一个配置类并实现WebMvcConfigurer 接口。
作用就和我们之前在xml中注册声明ssm的各项基本参数一样
@Configuration
public class LoginConfiguration implements WebMvcConfigurer {
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry){
// 注册拦截器
InterceptorRegistration loginRegistry = registry.addInterceptor(loginInterceptor());
// 拦截路径
loginRegistry.addPathPatterns("/**");
// 排除路径
loginRegistry.excludePathPatterns("/");
loginRegistry.excludePathPatterns("/auth/accredit");
/*loginRegistry.excludePathPatterns("/loginout");*/
// 排除资源请求
loginRegistry.excludePathPatterns("/css/login/*.css");
loginRegistry.excludePathPatterns("/js/login/**/*.js");
loginRegistry.excludePathPatterns("/image/login/*.png");
}
}
注意上面的@Bean形式声明的过滤器,这样才能让配置的加载都不出问题,才能让JwtProperties配置类读取到application.yml中的配置信息。这是由于拦截器的额加载是在springcontext之前的,所以要在这里来声明。
springboot使用jwt进行权限验证的更多相关文章
- SpringBoot集成JWT实现token验证
原文:https://www.jianshu.com/p/e88d3f8151db JWT官网: https://jwt.io/ JWT(Java版)的github地址:https://github. ...
- SpringBoot集成JWT实现权限认证
目录 一.JWT认证流程 二.SpringBoot整合JWT 三.测试 上一篇文章<一分钟带你了解JWT认证!>介绍了JWT的组成和认证原理,本文将介绍下SpringBoot整合JWT实现 ...
- Springboot Oauth2 集成Swagger2权限验证实战
Swagger是什么?能干什么?在这就不展开讲解了.本文主要讲解如何集成OAuth2的Password模式权限验证,验证接口是否具有权限. 引入依赖 <dependency> <gr ...
- SpringBoot整合Apache Shiro权限验证框架
比较常见的权限框架有两种,一种是Spring Security,另一种是Apache Shiro,两种框架各有优劣,个人感觉Shiro更容易使用,更加灵活,也更符合RABC规则,而且是java官方更推 ...
- springboot之JWT实现权限认证
1.在pom.xml添加依赖 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jw ...
- SpringBoot 使用jwt进行身份验证
这里只供参考,比较使用jwt方式进行身份验证感觉不好,最不行的就是不能退出 登陆时设定多长过期时间,只能等这个时间过了以后才算退出,服务端只能验证请求过来的token是否通过验证 Code: /** ...
- webapi使用jwt做权限验证
考虑到很多公司目前并没有切换到.netcore,所有本文尝试使用.netframework下的webapi 首先使用Nuget 安装 jwt包 安装完成后,创建 jwt的帮助类 public clas ...
- springboot、springsecurity、jwt权限验证
1.背景 基于前后端分离项目的后端模块: 2.相关技术 springboot全家桶 web模块 security模块:用于权限的验证 mongodb 模块:集成mogodb模块 jwt 用于token ...
- SpringBoot集成JWT 实现接口权限认证
JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的, 特别适用于分布式站点 ...
随机推荐
- Xshell(远程)连接不上linux服务器(防火墙介绍)
一.原因 远程(ssh)连接不上linux服务器的大多数原因都是因为本地服务器的防火墙策略导致的,因此我们想ssh远程能够连接上服务器,有两种方法: 修改防火墙策略 关闭防火墙 二.防火墙服务介绍 1 ...
- Jmeter(三十八) - 从入门到精通进阶篇 - 命令行运行JMeter详解(详解教程)
1.简介 前边一篇文章介绍了如何生成测试报告,细心地小伙伴或者同学们可以看到宏哥启动Jmeter生成测试报告不是在gui页面操作的,而是在gui页面设置好保存以后,用命令行来生成测试报告的.这一篇宏哥 ...
- python-3-2
一 切片 1.切片是list取值的一种方式 列子: nums = ['a','b','c','d','e','f','h','g','k','l','kk','nn','ee'] 取b和c元素出来 p ...
- Vue中的Xss构造
首发tools:https://www.t00ls.net/thread-59512-1-1.html 存储型XSS 最近做测试的时候碰到了一个前端页面使用了Vue框架的项目 在测试XSS漏洞的过程中 ...
- Nginx错误日志(error_log)配置及信息详解
Nginx错误日志信息介绍 Nginx的错误信息是调试Nginx服务的重要手段,属于核心功能模块(ngx_core_module)的参数,该参数的名字为error_log,可以放在Main区块中全局配 ...
- 敏捷史话(十三):我被 Facebook 解雇了——Kent Beck
2011年,Kent Beck 加入了 Facebook .那时候的他已年过半百,几十年的经验让他自认为非常了解软件行业.在 Facebook 的新手训练营期间,Kent 开始意识到,Facebook ...
- Vscode部分快捷键 Ps的简单使用 less中的除法问题 H5 四种布局
vscode 部分快捷键 ctrl+/ 注释ctrl+回车 光标下移alt+shift+上下箭头 将本行代码向上或向下复制ul>li 自动写alt ,鼠标一直点,就会有很多光标,可以一起写ctr ...
- 201871030108-冯永萍 实验二 个人项目— D{0-1}背包问题项目报告
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs.com/nwnu-dai ...
- 封装一个处理 react 异常的最简 ErrorBoundary 组件 🎅
前言 从 React 16 开始,引入了 Error Boundaries 概念,它可以捕获它的子组件中产生的错误,记录错误日志,并展示降级内容,具体 官网地址. 错误边界避免一个组件错误导致整个页面 ...
- Java(1-24)【前言、入门程序、常量、变量、类型转换】
如何输出规定结果,利用String.format System.out.println(String.format("%.2f", f)); 编译:是指将我们编写的Java源文件翻 ...