springboot之JWT实现权限认证
1、在pom.xml添加依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
2、自定义两个注解PassToken、UserLoginToken
package com.cn.commodity.annotations; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
boolean required() default true;
}
package com.cn.commodity.annotations; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
boolean required() default true;
}
3、定义一个获取token的服务TokenService
package com.cn.commodity.service; import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.cn.commodity.entity.User;
import org.springframework.stereotype.Service; @Service("tokenService")
public class TokenService { public String getToken(User user) { //生成token
String token="";
token= JWT.create().withAudience(String.valueOf(user.getId()))
.sign(Algorithm.HMAC256(user.getPassword()));
return token;
}
}
4、定义一个拦截器
package com.cn.commodity.interceptor; import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.cn.commodity.annotations.PassToken;
import com.cn.commodity.annotations.UserLoginToken;
import com.cn.commodity.entity.User;
import com.cn.commodity.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method; public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
UserService userService; @Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
// 如果不是映射到方法直接通过
if (!(object instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) object;
Method method = handlerMethod.getMethod();
//检查是否有passtoken注释,有则跳过认证
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
}
//检查有没有需要用户权限的注解
if (method.isAnnotationPresent(UserLoginToken.class)) {
UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
if (userLoginToken.required()) {
// 执行认证
if (token == null) {
throw new RuntimeException("无token,请重新登录");
}
// 获取 token 中的 user id
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new RuntimeException("401");
}
User user = userService.getUserById(Integer.parseInt(userId));
if (user == null) {
throw new RuntimeException("用户不存在,请重新登录");
}
// 验证 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new RuntimeException("401");
}
return true;
}
}
return true;
} @Override
public void postHandle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, ModelAndView modelAndView) throws Exception { } @Override
public void afterCompletion(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
}
}
5、在项目中应用该拦截器
package com.cn.commodity.interceptor; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor())
.addPathPatterns("/**"); // 拦截所有请求,通过判断是否有 @LoginRequired 注解 决定是否需要登录
}
@Bean
public AuthenticationInterceptor authenticationInterceptor() {
return new AuthenticationInterceptor();
}
}
6、在controller层应用注解进行验证
package com.cn.commodity.controller; import com.alibaba.fastjson.JSONObject;
import com.cn.commodity.annotations.PassToken;
import com.cn.commodity.annotations.UserLoginToken;
import com.cn.commodity.dao.UserDao;
import com.cn.commodity.entity.User;
import com.cn.commodity.service.TokenService;
import com.cn.commodity.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController
@RequestMapping("api")
public class UserApi {
@Autowired
UserService userService;
@Autowired
TokenService tokenService; @Resource
private UserDao userDao;
//登录
@PostMapping("/login")
public Object login(@RequestBody User user){
JSONObject jsonObject=new JSONObject();
//User userForBase=userService.getUserById(user.getId());
User userForBase=userDao.selectOne(user);
if(userForBase==null){
jsonObject.put("message","登录失败,用户不存在");
return jsonObject;
}else {
if (!userForBase.getPassword().equals(user.getPassword())){
jsonObject.put("message","登录失败,密码错误");
return jsonObject;
}else {
String token = tokenService.getToken(userForBase);
jsonObject.put("token", token);
jsonObject.put("user", userForBase);
return jsonObject;
}
}
}
@UserLoginToken
@GetMapping("/getMessage")
public String getMessage(){
return "你已通过验证";
} @PassToken
@GetMapping("/skipToken")
public String skipToken(){
return "跳过passToken认证";
}
}
7、运行测试
a) 登陆获取token
#获取token,在项目中可以将token和user组合存在redis中。
post请求参数:
{
"userName":"yangwj1",
"password":"wj1"
} 请求url:http://localhost:8080/api/login 返回参数:
{
"user": {
"id": 2,
"userName": "yangwj1",
"password": "wj1",
"age": 1
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyIn0.z2EzbIbYLCmw5PM5Yx9arE5QGUH9ET_AC0BEy9SyE8A"
}
b)跳过token认证
请求url:http://localhost:8080/api/skipToken
返回参数:跳过passToken认证
c)对api进行token验证
请求参数header中:
token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyIn0.z2EzbIbYLCmw5PM5Yx9arE5QGUH9ET_AC0BEy9SyE8A 请求url:http://localhost:8080/api/getMessage 返回参数:你已通过验证
springboot之JWT实现权限认证的更多相关文章
- SpringBoot集成JWT实现权限认证
目录 一.JWT认证流程 二.SpringBoot整合JWT 三.测试 上一篇文章<一分钟带你了解JWT认证!>介绍了JWT的组成和认证原理,本文将介绍下SpringBoot整合JWT实现 ...
- springboot使用jwt进行权限验证
springboot使用jwt进行权限验证 依赖准备 首先导入对应的依赖 <dependencies> <dependency> <groupId>org.apac ...
- SpringBoot整合JWT实现登录认证
什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...
- spring-boot整合shiro作权限认证
spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro 废话不多说 引入pom文件 <!--shiro集成spring--& ...
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- Shiro-JWT SpringBoot前后端分离权限认证的一种思路
JWT-Shiro 整合 JWT-与Shiro整合进行授权认证的大致思路 图示 大致思路 将登录验证从shiro中分离,自己结合JWT实现 用户登陆后请求认证服务器进行密码等身份信息确认,确认成功后 ...
- 轻松上手SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制实战
前言 我们知道在项目开发中,后台开发权限认证是非常重要的,springboot 中常用熟悉的权限认证框架有,shiro,还有就是springboot 全家桶的 security当然他们各有各的好处,但 ...
- JWT实现登录认证实例
JWT全称JSON Web Token,是一个紧凑的,自包含的,安全的信息交换协议.JWT有很多方面的应用,例如权限认证,信息交换等.本文将简单介绍JWT登录权限认证的一个实例操作. JWT组成 JW ...
- SpringBoot系列 - 集成JWT实现接口权限认证
会飞的污熊 2018-01-22 16173 阅读 spring jwt springboot RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authenticati ...
随机推荐
- 【appium】appium中的元素定位和基本操作
# coding=utf-8 from appium import webdriver import time from selenium.webdriver.support.ui import We ...
- 快速认识Python
1.数字和表达式 什么是表达式,1+2*3 就是一个表达式,这里的加号和乘号叫做运算符,1.2.3叫做操作数.1+2*3 经过计算后得到的结果是7,就1+2*3 = 7.我们可以将计算结果保存在一个变 ...
- Java 中的多态,一次讲个够之接口实现关系中的多态
上文还没有写完,这一篇继续 Java 中的多态,一次讲个够之继承关系中的多态 https://www.cnblogs.com/qianjinyan/p/10824576.html 接口实现关系,和继承 ...
- SpringMVC 一次请求加载Controller多次
原因之一:HTML页面中 css样式 background:url() 或 img.iframe标签 src设置为空 例:<div style="background:url()&qu ...
- phpstorm和ftp搭配使用
简单使用
- tycho 打包编译报错 Access restriction: The type XYZ is not API
解决办法: 在pom.xml中加入以下配置 <plugin> <groupId>org.eclipse.tycho</groupId> <artifactId ...
- 2019牛客多校D move——乱搞&&思维题
题意 给定 $n$ 个物品,体积分别为 $v_i$,现有 $K$ 的容积一样的箱子,按如下策略装入物品:每次选取尽可能大的装入(较大的不能装入时可以向小的找),依次装入箱子. 分析 首先,不具有严格的 ...
- 【基础算法-树状数组】入门-C++
目录 基本定义 如何理解树状数组 主要操作 @ 基本定义 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构. ...
- Web service stop after running serveral hours
Error Message: 1. Error:Web service call "Test" execution failed 2. Error:<CENTER>&l ...
- kernel namespace
reference: https://lwn.net/Articles/531114/