SpringBoot 基于jjwt快速实现token授权
1、添加maven依赖注解
<!--JJWT库-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
2、添加登录获取token时,所需要的认证信息类LoginPara.Java
/**
* 添加登录获取token时,所需要的认证信息类LoginPara.Java
* Created by CatalpaFlat on 2017/8/29.
*/
public class LoginPara {
private String clientId;
private String userName;
private String password;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
3、添加token返回结果类AccessToken.java
/**
* 添加token返回结果类AccessToken.java
* Created by CatalpaFlat on 2017/8/29.
*/
public class AccessToken {
private String access_token;
private String token_type;
private long expires_in;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getToken_type() {
return token_type;
}
public void setToken_type(String token_type) {
this.token_type = token_type;
}
public long getExpires_in() {
return expires_in;
}
public void setExpires_in(long expires_in) {
this.expires_in = expires_in;
}
}
4、添加用于拼装token认证TokenObject类
/**
* Created by CatalpaFlat on 2017/8/31.
*/
@Component
public class TokenObject {
/**客户端id*/
private String clientId;
/**base64加密*/
private String base64Secret;
/**用户名*/
private String name;
/**到期时间*/
private long expiresSecond;
/**管理员名称*/
private String userName;
/**管理员id*/
private Integer aId;
/**职能*/
private String role;
/**项目名称*/
private String project;
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getBase64Secret() {
return base64Secret;
}
public void setBase64Secret(String base64Secret) {
this.base64Secret = base64Secret;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getExpiresSecond() {
return expiresSecond;
}
public void setExpiresSecond(long expiresSecond) {
this.expiresSecond = expiresSecond;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getaId() {
return aId;
}
public void setaId(Integer aId) {
this.aId = aId;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
5、添加构造jwt及解析jwt的帮助类JwtHelper.java
/**
* 添加构造jwt及解析jwt的帮助类JwtHelper.java
* Created by CatalpaFlat on 2017/8/29.
*/
public class JwtHelper {
private static Logger logger = LoggerFactory.getLogger(JwtHelper.class);
/**
* 校验Token
* @param jwt
* @param httpRequest
* @return
*/
public static int checkToken(String jwt, HttpServletRequest httpRequest){
if (!StringUtils.isBlank(jwt)){
if (jwt.split("\\.").length==3) {
logger.info("jwt:" + jwt);
String[] split = jwt.split("\\.");
String content = split[1];
String s = Base64Codec.BASE64URL.decodeToString(content);
logger.info("s:" + s);
String sign = split[2];
logger.info("sign:" + sign);
JSONObject jsonObject1 = JSONObject.fromObject(s);
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
long expiresSecond = (long) jsonObject1.get("expiresSecond");
//判断是否过期
if(now.getTime()>expiresSecond)
return 2;
TokenObject o = (TokenObject) JSONObject.toBean(jsonObject1, TokenObject.class);
if (o!=null){
String project = o.getProject();
if (!StaticInfo.PROJECT.equals(project))
return 0;
}
String jwtByStr = createJWTByObj(o);
String s2 = jwtByStr.split("\\.")[2];
logger.info("s2:" + s2);
if (sign.equals(s2)) {
return 1;
} else
return 0;
}
}
return 0;
}
/**
* 获取用户id
* @param jwt
* @return
*/
public static int getIdByJWT(String jwt){
if (!StringUtils.isBlank(jwt)) {
if (jwt.split("\\.").length == 3) {
logger.info("jwt:" + jwt);
String[] split = jwt.split("\\.");
String content = split[1];
String s = Base64Codec.BASE64URL.decodeToString(content);
JSONObject jsonObject1 = JSONObject.fromObject(s);
TokenObject o = (TokenObject) JSONObject.toBean(jsonObject1, TokenObject.class);
return o.getaId();
}
}
return 0;
}
/**
* 获取客户信息
* @param request
* @return
* @throws CustomException
*/
public static int getIdByRequest(HttpServletRequest request) throws CustomException {
int i = 0;
String auth = request.getHeader("Authorization");
if ((auth != null) && (auth.length() > 6)) {
String HeadStr = auth.substring(0, 5).toLowerCase();
if (HeadStr.compareTo("basic") == 0) {
auth = auth.substring(6, auth.length());
i = JwtHelper.getIdByJWT(auth);
}
}
if (i==0)
throw new CustomException(ResultEnum.PERMISSION_DENIED);
return i;
}
public static String createJWTByObj(TokenObject tokenObject) {
JSONObject jsonObject = JSONObject.fromObject(tokenObject);
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//生成签名密钥
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(tokenObject.getBase64Secret());
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//添加构成JWT的参数
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setPayload(jsonObject.toString())
.signWith(signatureAlgorithm, signingKey);
//生成JWT
return builder.compact();
}
}
6、添加token过滤器
(如果请求的Header中存在Authorization: Basic 头信息,且用户名密码正确,则继续原来的请求,否则返回没有权限的错误信息)
/**
* 如果请求的Header中存在Authorization: Basic 头信息,且用户名密码正确,则继续原来的请求,否则返回没有权限的错误信息
*/
@WebFilter(filterName = "colationFilter", urlPatterns= "/colation/*")
public class HTTPBasicAuthorizeAttribute implements Filter{
private Logger logger = LoggerFactory.getLogger(HTTPBasicAuthorizeAttribute.class);
@Autowired
private Audience audience;
@Override
public void destroy() {
logger.info("后台token过滤器,溜了溜了溜了溜了");
//可以日志管理添加
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("后台token过滤器检测");
//1.检测当前是否需要重新登录
if(audience!=null){
if (audience.getClientId().equals(StaticInfo.SIGNOUT)){
toResponse((HttpServletResponse) response,1,(HttpServletRequest) request);
return;
}
}
//2.检测请求同token信息
ResultEnum resultStatusCode = checkHTTPBasicAuthorize(request);
if (resultStatusCode.equals(ResultEnum.SINGTIMEOUT)){//超时
toResponse((HttpServletResponse) response, 2,(HttpServletRequest) request);
return;
}else if (resultStatusCode.equals(ResultEnum.PERMISSION_DENIED)){//权限不够
toResponse((HttpServletResponse) response, 0,(HttpServletRequest) request);
return;
}
logger.info("后台token过滤器检测通过");
chain.doFilter(request, response);
}
/**
* 响应
* @param response
* @param i 类型
* @throws IOException
*/
private void toResponse(HttpServletResponse response, int i,HttpServletRequest request) throws IOException {
HttpServletResponse httpResponse = response;
httpResponse.setCharacterEncoding("UTF-8");
httpResponse.setContentType("application/json; charset=utf-8");
httpResponse.setHeader("Access-Control-Allow-Origin","*");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PATCH,PUT");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,x-requested-with,X-Custom-Header," +
"Content-Type,Accept,Authorization");
String method = request.getMethod();
if ("OPTIONS".equalsIgnoreCase(method)){
logger.info("OPTIONS请求");
httpResponse.setStatus(HttpServletResponse.SC_ACCEPTED);
}
ObjectMapper mapper = new ObjectMapper();
PrintWriter writer = httpResponse.getWriter();
if (i==1)
writer.write(mapper.writeValueAsString(ResultUtils.error(ResultEnum.RESTARTLOGIN)));
else if (i==2)
writer.write(mapper.writeValueAsString(ResultUtils.error(ResultEnum.SINGTIMEOUT)));
else
writer.write(mapper.writeValueAsString(ResultUtils.error(ResultEnum.PERMISSION_DENIED)));
writer.close();
if (writer!=null)
writer = null;
}
@Override
public void init(FilterConfig arg0) throws ServletException {
logger.info("后台token过滤器启动");
}
/**
* 检测请求同token信息
* @param request
* @return
*/
private ResultEnum checkHTTPBasicAuthorize(ServletRequest request)
{
try
{
HttpServletRequest httpRequest = (HttpServletRequest)request;
String auth = httpRequest.getHeader("Authorization");
if ((auth != null) && (auth.length() > 6))
{
String HeadStr = auth.substring(0, 5).toLowerCase();
if (HeadStr.compareTo("basic") == 0)
{
auth = auth.substring(6, auth.length());
int i = JwtHelper.checkToken(auth, httpRequest);
if (i==1) {
return ResultEnum.OK;
}else if (i==2){
return ResultEnum.SINGTIMEOUT;
}
}
}
return ResultEnum.PERMISSION_DENIED;
}
catch(Exception ex)
{
return ResultEnum.PERMISSION_DENIED;
}
}
}
7、测试token
/**
* 登录退出-Controller
* Created by CatalpaFlat on 2017/8/31.
*/
@RestController
@RequestMapping
public class AccoutController {
@Autowired
private AccountService accountService;
/**
* 登录
* @param loginPara
* @param request
* @return
* @throws CustomException
*/
@PostMapping(value = "oauth/token")
public Result getToken(LoginPara loginPara, HttpServletRequest request) throws CustomException {
return accountService.getToken(loginPara,request);
}
/**
* 退出
* @param request
* @return
*/
@PostMapping(value = "singOut")
public Result singOut(HttpServletRequest request){
return accountService.singOut(request);
}
}
/**
* 登录-ServiceImpl
* Created by CatalpaFlat on 2017/8/29.
*/
@Service
public class AccountServiceImpl implements AccountService {
private Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);
@Autowired
private AccountMapper accountMapper;
@Autowired
private Audience audience;
@Autowired
private TokenObject tokenObject;
@Override
public MangerInfo queryAccountByName(String userName) {
return accountMapper.queryAccountByName(userName);
}
/**
* 获取token
* @param loginPara
* @param request
* @return
*/
@Override
public Result getToken(LoginPara loginPara, HttpServletRequest request) throws CustomException {
//获取登录ip
String remoteHost = request.getRemoteHost();
String md5 = MD5Utils.getMD5(remoteHost);
logger.info("md5:"+md5);
loginPara.setClientId(md5);
//第一个登录者
if (StaticInfo.SIGNOUT.equals(audience.getClientId())){
//修改配置文件
BeanWrapper bean = new BeanWrapperImpl(audience);
bean.setPropertyValue("clientId", md5);
audience.setClientId(md5);
}
audience.setClientId(md5);
//校验是否已经登录着
// if(audience.getClientId()!=null&&(loginPara.getClientId().compareTo(audience.getClientId()) != 0))
// throw new CustomException(ResultEnum.ISSINGIMG);
MangerInfo user = queryAccountByName(loginPara.getUserName());
if (user == null)
throw new CustomException(ResultEnum.INVALID_PASSWORD);
else
{
String md5Password = MD5Utils.getMD5(loginPara.getPassword()+user.getSalt());
if (md5Password.compareTo(user.getaPassword()) != 0)
throw new CustomException(ResultEnum.INVALID_PASSWORD);
}
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//拼装accessToken
tokenObject.setaId(user.getaId());
tokenObject.setBase64Secret(audience.getBase64Secret());
tokenObject.setClientId(audience.getClientId());
tokenObject.setExpiresSecond(audience.getExpiresSecond()+now.getTime());
tokenObject.setRole(user.getRole());
tokenObject.setUserName(loginPara.getUserName());
tokenObject.setName(audience.getName());
String token = JwtHelper.createJWTByObj(tokenObject);
//返回accessToken
AccessToken accessTokenEntity = new AccessToken();
accessTokenEntity.setAccess_token(token);
accessTokenEntity.setExpires_in(audience.getExpiresSecond());
accessTokenEntity.setToken_type("basic");
return ResultUtils.success(accessTokenEntity);
}
@Override
public Result singOut(HttpServletRequest request) {
BeanWrapper bean = new BeanWrapperImpl(audience);
bean.setPropertyValue("clientId", StaticInfo.SIGNOUT);
return ResultUtils.success();
}
}
SpringBoot 基于jjwt快速实现token授权的更多相关文章
- SpringBoot 通过jjwt快速实现token授权
A 10分钟了解JSON Web令牌(JWT)https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=p ...
- 在线Online表单来了!JeecgBoot 2.1 版本发布——基于SpringBoot+AntDesign的快速开发平台
项目介绍 Jeecg-Boot 是一款基于SpringBoot+代码生成器的快速开发平台! 采用前后端分离架构:SpringBoot,Ant-Design-Vue,Mybatis,Shiro,JWT. ...
- 基于SpringBoot+AntDesign的快速开发平台,JeecgBoot 2.0.2 版本发布
Jeecg-Boot 是一款基于SpringBoot+代码生成器的快速开发平台! 采用前后端分离架构:SpringBoot,Ant-Design-Vue,Mybatis,Shiro,JWT. 强大的代 ...
- springboot+jwt做api的token认证
本篇和大家分享jwt(json web token)的使用,她主要用来生成接口访问的token和验证,其单独结合springboot来开发api接口token验证很是方便,由于jwt的token中存储 ...
- SpringBoot系列: RestTemplate 快速入门
====================================相关的文章====================================SpringBoot系列: 与Spring R ...
- Windows Azure Active Directory (1) 前言 - 基于声明的验证和授权
<Windows Azure Platform 系列文章目录> 在我们介绍整套系统架构之前,我们需要首先定义一些基本的概念. 用户及其属性: 用户值得是要使用某项服务的个体.用户一般都有一 ...
- ABP从入门到精通(5):使用基于JWT标准的Token访问WebApi
项目:asp.net zero 4.2.0 .net core(1.1) 版本 我们做项目的时候可能会遇到需要提供api给app调用,ABP动态生成的WebApi提供了方便的基于JWT标准的Token ...
- spring-security实现的token授权
在我的用户密码授权文章里介绍了spring-security的工作过程,不了解的同学,可以先看看用户密码授权这篇文章,在 用户密码授权模式里,主要是通过一个登陆页进行授权,然后把授权对象写到sessi ...
- 基于vue-cli快速构建
基于vue-cli快速构建 https://www.jianshu.com/p/2769efeaa10a Vue是近两年来比较火的一个前端框架(渐进式框架吧),与reactjs和angularjs ...
随机推荐
- 洛谷 P1886 滑动窗口 (数据与其他网站不同。。)
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- windows ubuntu bcdeditor
双系统. 先装windows,后装ubuntu12.04 为了避免grub引导,所以安装bcdeditor. 平时使用没有什么不适,可是每次linux升级内核以后,grub列表可能就会消失,自然是不能 ...
- kafka可视化客户端工具(Kafka Tool)安装
参考:https://www.cnblogs.com/frankdeng/p/9452982.html
- Bzoj 3307 雨天的尾巴(线段树合并+树上差分)
C. 雨天的尾巴 题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式 第 ...
- ''tensorflow.python.framework.errors_impl.ResourceExhaustedError: OOM when allocating tensor with shape[?]'' 错误分析
这是tensorflow 一个经常性错误,错误的原因在于:显卡内存不够. 解决方法就是降低显卡的使用内存,途径有以下几种措施: 1 减少Batch 的大小 2 分析错误的位置,在哪一层出现显卡不够,比 ...
- HNOI 2010 物品调度 并查集 置换
题意: 题意有点细,暂不概括.请仔细审题. 分析: 我们先要把c生成出来. 记得颜神讲这道题,首先表明,这道题有两个问题需要处理. 第一个是要先定位,第二个是要求最小移动步数. 定位时对于每一个物品i ...
- 对 Spring IoC 的理解
理解 “ 控制反转(IoC)” 控制反转(IoC):用白话来讲,就是由 Spring 容器控制程序中类与类之间的关系,而非传统实现中,由程序代码直接操控.这也就是所谓 “控制反转” 的概念所在:控制权 ...
- Ajax实现跨域访问最新方式
在实际项目当中,我们经常会遇到同一个域名下不同项目之间通过Ajax相互调用数据,这样问题就来了,如何通过Ajax实现跨域呢? 解决方案 1.Jsonp Jsonp解决跨域相对简单,服务器无需任何配置. ...
- MySQL简单查询和单表查询
MySQL记录操作 概览 MySQL数据操作: DML 在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用 ...
- python+selenium之元素的八大定位方法
以百度搜索框为例,先打开百度网页 1.点右上角爬虫按钮 2.点左下角箭头 3.讲箭头移动到百度搜索输入框上,输入框高亮状态 4.下方红色区域就是单位到输入框的属性: <input id=&quo ...