Commit 997d8e63 by wilmiam

1.0.0

parent b762e622
......@@ -40,8 +40,6 @@ public class LoginProperties {
private LoginCode loginCode;
public static final String cacheKey = "USER-LOGIN-DATA";
public boolean isSingleLogin() {
return singleLogin;
}
......
......@@ -19,6 +19,7 @@ import com.zq.admin.modules.security.service.OnlineUserService;
import com.zq.admin.modules.security.service.UserCacheManager;
import com.zq.common.annotation.AnonymousAccess;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import com.zq.common.utils.RequestMethodEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
......
......@@ -18,6 +18,7 @@ package com.zq.admin.config.security;
import com.zq.admin.modules.security.service.OnlineUserService;
import com.zq.admin.modules.security.service.UserCacheManager;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
......
......@@ -19,6 +19,7 @@ import cn.hutool.core.util.StrUtil;
import com.zq.admin.modules.security.service.OnlineUserService;
import com.zq.admin.modules.security.service.UserCacheManager;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import com.zq.common.context.ContextUtils;
import com.zq.common.vo.OnlineUserDto;
import io.jsonwebtoken.ExpiredJwtException;
......
package com.zq.admin.config.security;/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.zq.common.config.redis.RedisUtils;
import com.zq.common.config.security.SecurityProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* @author /
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class TokenProvider implements InitializingBean {
private final RedisUtils redisUtils;
private final SecurityProperties properties;
public static final String AUTHORITIES_KEY = "auth";
private static Key key;
private static SignatureAlgorithm signatureAlgorithm;
@Override
public void afterPropertiesSet() {
signatureAlgorithm = SignatureAlgorithm.HS512;
byte[] keyBytes = DatatypeConverter.parseBase64Binary(properties.getBase64Secret());
key = new SecretKeySpec(keyBytes, signatureAlgorithm.getJcaName());
}
public static String createToken(Authentication authentication) {
return Jwts.builder()
.claim(AUTHORITIES_KEY, authentication.getName())
.setSubject(authentication.getName())
.signWith(signatureAlgorithm, key)
// 加入ID确保生成的 Token 都不一致
.setId(IdUtil.simpleUUID())
.compact();
}
public Claims getClaims(String token) {
return Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
.parseClaimsJws(token)
.getBody();
}
public Authentication getAuthentication(String token) {
Claims claims = getClaims(token);
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
}
/**
* @param token 需要检查的token
*/
public void checkRenewal(String token) {
// 判断是否续期token,计算token的过期时间
long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
// 判断当前时间与过期时间的时间差
long differ = expireDate.getTime() - System.currentTimeMillis();
// 如果在续期检查的范围内,则续期
if (differ <= properties.getDetect()) {
long renew = time + properties.getRenew();
redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
}
}
public String getToken(HttpServletRequest request) {
String bearerToken = request.getHeader(properties.getHeader());
if (StringUtils.isBlank(bearerToken)) {
return null;
}
if (bearerToken.startsWith(properties.getTokenStartWith())) {
// 去掉令牌前缀
return bearerToken.replace(properties.getTokenStartWith(), "");
} else {
log.debug("非法Token:{}", bearerToken);
}
return null;
}
}
// package com.zq.admin.config.security;/*
// * Copyright 2019-2020 Zheng Jie
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
// import cn.hutool.core.date.DateField;
// import cn.hutool.core.date.DateUtil;
// import cn.hutool.core.util.IdUtil;
// import com.zq.common.config.redis.RedisUtils;
// import com.zq.common.config.security.SecurityProperties;
// import io.jsonwebtoken.Claims;
// import io.jsonwebtoken.Jwts;
// import io.jsonwebtoken.SignatureAlgorithm;
// import lombok.RequiredArgsConstructor;
// import lombok.extern.slf4j.Slf4j;
// import org.apache.commons.lang3.StringUtils;
// import org.springframework.beans.factory.InitializingBean;
// import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
// import org.springframework.security.core.Authentication;
// import org.springframework.security.core.userdetails.User;
// import org.springframework.stereotype.Component;
//
// import javax.crypto.spec.SecretKeySpec;
// import javax.servlet.http.HttpServletRequest;
// import javax.xml.bind.DatatypeConverter;
// import java.security.Key;
// import java.util.ArrayList;
// import java.util.Date;
// import java.util.concurrent.TimeUnit;
//
// /**
// * @author /
// */
// @Slf4j
// @Component
// @RequiredArgsConstructor
// public class TokenProvider implements InitializingBean {
//
// private final RedisUtils redisUtils;
// private final SecurityProperties properties;
//
// public static final String AUTHORITIES_KEY = "auth";
// private static Key key;
// private static SignatureAlgorithm signatureAlgorithm;
//
// @Override
// public void afterPropertiesSet() {
// signatureAlgorithm = SignatureAlgorithm.HS512;
// byte[] keyBytes = DatatypeConverter.parseBase64Binary(properties.getBase64Secret());
// key = new SecretKeySpec(keyBytes, signatureAlgorithm.getJcaName());
// }
//
// public static String createToken(Authentication authentication) {
// return Jwts.builder()
// .claim(AUTHORITIES_KEY, authentication.getName())
// .setSubject(authentication.getName())
// .signWith(signatureAlgorithm, key)
// // 加入ID确保生成的 Token 都不一致
// .setId(IdUtil.simpleUUID())
// .compact();
// }
//
// public Claims getClaims(String token) {
// return Jwts.parser()
// .setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
// .parseClaimsJws(token)
// .getBody();
// }
//
// public Authentication getAuthentication(String token) {
// Claims claims = getClaims(token);
// User principal = new User(claims.getSubject(), "******", new ArrayList<>());
// return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
// }
//
// /**
// * @param token 需要检查的token
// */
// public void checkRenewal(String token) {
// // 判断是否续期token,计算token的过期时间
// long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
// Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
// // 判断当前时间与过期时间的时间差
// long differ = expireDate.getTime() - System.currentTimeMillis();
// // 如果在续期检查的范围内,则续期
// if (differ <= properties.getDetect()) {
// long renew = time + properties.getRenew();
// redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
// }
// }
//
// public String getToken(HttpServletRequest request) {
// String bearerToken = request.getHeader(properties.getHeader());
// if (StringUtils.isBlank(bearerToken)) {
// return null;
// }
// if (bearerToken.startsWith(properties.getTokenStartWith())) {
// // 去掉令牌前缀
// return bearerToken.replace(properties.getTokenStartWith(), "");
// } else {
// log.debug("非法Token:{}", bearerToken);
// }
// return null;
// }
//
// }
......@@ -186,7 +186,7 @@ public class DeployServiceImpl implements DeployService {
private void sleep(int second) {
try {
Thread.sleep(second * 1000);
Thread.sleep(second * 1000L);
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
......@@ -219,7 +219,6 @@ public class DeployServiceImpl implements DeployService {
private void stopApp(int port, ExecuteShellUtil executeShellUtil) {
//发送停止命令
executeShellUtil.execute(String.format("lsof -i :%d|grep -v \"PID\"|awk '{print \"kill -9\",$2}'|sh", port));
}
/**
......
......@@ -20,7 +20,6 @@ import com.wf.captcha.base.Captcha;
import com.zq.admin.config.RsaProperties;
import com.zq.admin.config.bean.LoginCodeEnum;
import com.zq.admin.config.bean.LoginProperties;
import com.zq.admin.config.security.TokenProvider;
import com.zq.admin.exception.BadRequestException;
import com.zq.admin.modules.security.service.OnlineUserService;
import com.zq.admin.modules.security.service.dto.AuthUserDto;
......@@ -32,6 +31,7 @@ import com.zq.common.annotation.rest.AnonymousGetMapping;
import com.zq.common.annotation.rest.AnonymousPostMapping;
import com.zq.common.config.redis.RedisUtils;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
......
......@@ -16,8 +16,8 @@
package com.zq.admin.modules.security.service;
import cn.hutool.core.util.RandomUtil;
import com.zq.admin.config.bean.LoginProperties;
import com.zq.admin.modules.security.service.dto.JwtUserDto;
import com.zq.common.config.redis.BaseCacheKeys;
import com.zq.common.config.redis.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
......@@ -48,7 +48,7 @@ public class UserCacheManager {
public JwtUserDto getUserCache(String userName) {
if (StringUtils.isNotEmpty(userName)) {
// 获取数据
Object obj = redisUtils.hget(LoginProperties.cacheKey, userName);
Object obj = redisUtils.hget(BaseCacheKeys.USER_DATA_MAP_KEY, userName);
if (obj != null) {
return (JwtUserDto) obj;
}
......@@ -66,7 +66,7 @@ public class UserCacheManager {
if (StringUtils.isNotEmpty(userName)) {
// 添加数据, 避免数据同时过期
long time = idleTime + RandomUtil.randomInt(900, 1800);
redisUtils.hset(LoginProperties.cacheKey, userName, user, time);
redisUtils.hset(BaseCacheKeys.USER_DATA_MAP_KEY, userName, user, time);
}
}
......@@ -80,7 +80,7 @@ public class UserCacheManager {
public void cleanUserCache(String userName) {
if (StringUtils.isNotEmpty(userName)) {
// 清除数据
redisUtils.hdel(LoginProperties.cacheKey, userName);
redisUtils.hdel(BaseCacheKeys.USER_DATA_MAP_KEY, userName);
}
}
......
......@@ -18,6 +18,7 @@ package com.zq.user.config;
import com.zq.common.annotation.AnonymousAccess;
import com.zq.common.config.redis.RedisUtils;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import com.zq.common.utils.RequestMethodEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
......
......@@ -17,6 +17,7 @@ package com.zq.user.config;
import com.zq.common.config.redis.RedisUtils;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
......
......@@ -16,8 +16,10 @@
package com.zq.user.config;
import cn.hutool.core.util.StrUtil;
import com.zq.common.config.redis.BaseCacheKeys;
import com.zq.common.config.redis.RedisUtils;
import com.zq.common.config.security.SecurityProperties;
import com.zq.common.config.security.TokenProvider;
import com.zq.common.context.ContextUtils;
import com.zq.common.vo.OnlineUserDto;
import io.jsonwebtoken.ExpiredJwtException;
......@@ -74,7 +76,8 @@ public class TokenFilter extends GenericFilterBean {
cleanUserCache = true;
} finally {
if (cleanUserCache || Objects.isNull(onlineUserDto)) {
// userCacheClean.cleanUserCache(String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY)));
String username = String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY));
redisUtils.hdel(BaseCacheKeys.USER_DATA_MAP_KEY, username);
}
}
if (onlineUserDto != null && StringUtils.isNotBlank(token)) {
......
package com.zq.user.config;/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zq.common.config.redis.RedisUtils;
import com.zq.common.config.security.SecurityProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author /
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class TokenProvider implements InitializingBean {
private final RedisUtils redisUtils;
private final SecurityProperties properties;
public static final String AUTHORITIES_KEY = "auth";
private static Key key;
private static SignatureAlgorithm signatureAlgorithm;
@Override
public void afterPropertiesSet() {
signatureAlgorithm = SignatureAlgorithm.HS512;
byte[] keyBytes = DatatypeConverter.parseBase64Binary(properties.getBase64Secret());
key = new SecretKeySpec(keyBytes, signatureAlgorithm.getJcaName());
}
public static String createToken(Authentication authentication) {
String authorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
return Jwts.builder()
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, authorities)
.signWith(signatureAlgorithm, key)
// 加入ID确保生成的 Token 都不一致
.setId(IdUtil.simpleUUID())
.compact();
}
public Claims getClaims(String token) {
return Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
.parseClaimsJws(token)
.getBody();
}
public Authentication getAuthentication(String token) {
Claims claims = Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
.parseClaimsJws(token)
.getBody();
// fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
Object authoritiesStr = claims.get(AUTHORITIES_KEY);
Collection<? extends GrantedAuthority> authorities =
ObjectUtil.isNotEmpty(authoritiesStr) ?
Arrays.stream(authoritiesStr.toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()) : Collections.emptyList();
User principal = new User(claims.getSubject(), "******", authorities);
return new UsernamePasswordAuthenticationToken(principal, token, authorities);
}
/**
* @param token 需要检查的token
*/
public void checkRenewal(String token) {
// 判断是否续期token,计算token的过期时间
long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
// 判断当前时间与过期时间的时间差
long differ = expireDate.getTime() - System.currentTimeMillis();
// 如果在续期检查的范围内,则续期
if (differ <= properties.getDetect()) {
long renew = time + properties.getRenew();
redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
}
}
public String getToken(HttpServletRequest request) {
String bearerToken = request.getHeader(properties.getHeader());
if (StringUtils.isBlank(bearerToken)) {
return null;
}
if (bearerToken.startsWith(properties.getTokenStartWith())) {
// 去掉令牌前缀
return bearerToken.replace(properties.getTokenStartWith(), "");
} else {
log.debug("非法Token:{}", bearerToken);
}
return null;
}
}
// package com.zq.user.config;/*
// * Copyright 2019-2020 Zheng Jie
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
// import cn.hutool.core.date.DateField;
// import cn.hutool.core.date.DateUtil;
// import cn.hutool.core.util.IdUtil;
// import cn.hutool.core.util.ObjectUtil;
// import com.zq.common.config.redis.RedisUtils;
// import com.zq.common.config.security.SecurityProperties;
// import io.jsonwebtoken.Claims;
// import io.jsonwebtoken.Jwts;
// import io.jsonwebtoken.SignatureAlgorithm;
// import lombok.RequiredArgsConstructor;
// import lombok.extern.slf4j.Slf4j;
// import org.apache.commons.lang3.StringUtils;
// import org.springframework.beans.factory.InitializingBean;
// import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
// import org.springframework.security.core.Authentication;
// import org.springframework.security.core.GrantedAuthority;
// import org.springframework.security.core.authority.SimpleGrantedAuthority;
// import org.springframework.security.core.userdetails.User;
// import org.springframework.stereotype.Component;
//
// import javax.crypto.spec.SecretKeySpec;
// import javax.servlet.http.HttpServletRequest;
// import javax.xml.bind.DatatypeConverter;
// import java.security.Key;
// import java.util.Arrays;
// import java.util.Collection;
// import java.util.Collections;
// import java.util.Date;
// import java.util.concurrent.TimeUnit;
// import java.util.stream.Collectors;
//
// /**
// * @author /
// */
// @Slf4j
// @Component
// @RequiredArgsConstructor
// public class TokenProvider implements InitializingBean {
//
// private final RedisUtils redisUtils;
// private final SecurityProperties properties;
//
// public static final String AUTHORITIES_KEY = "auth";
// private static Key key;
// private static SignatureAlgorithm signatureAlgorithm;
//
// @Override
// public void afterPropertiesSet() {
// signatureAlgorithm = SignatureAlgorithm.HS512;
// byte[] keyBytes = DatatypeConverter.parseBase64Binary(properties.getBase64Secret());
// key = new SecretKeySpec(keyBytes, signatureAlgorithm.getJcaName());
// }
//
// public static String createToken(Authentication authentication) {
// String authorities = authentication.getAuthorities().stream()
// .map(GrantedAuthority::getAuthority)
// .collect(Collectors.joining(","));
//
// return Jwts.builder()
// .setSubject(authentication.getName())
// .claim(AUTHORITIES_KEY, authorities)
// .signWith(signatureAlgorithm, key)
// // 加入ID确保生成的 Token 都不一致
// .setId(IdUtil.simpleUUID())
// .compact();
// }
//
// public Claims getClaims(String token) {
// return Jwts.parser()
// .setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
// .parseClaimsJws(token)
// .getBody();
// }
//
// public Authentication getAuthentication(String token) {
// Claims claims = getClaims(token);
//
// // fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
// Object authoritiesStr = claims.get(AUTHORITIES_KEY);
// Collection<? extends GrantedAuthority> authorities =
// ObjectUtil.isNotEmpty(authoritiesStr) ?
// Arrays.stream(authoritiesStr.toString().split(","))
// .map(SimpleGrantedAuthority::new)
// .collect(Collectors.toList()) : Collections.emptyList();
//
// User principal = new User(claims.getSubject(), "******", authorities);
//
// return new UsernamePasswordAuthenticationToken(principal, token, authorities);
// }
//
// /**
// * @param token 需要检查的token
// */
// public void checkRenewal(String token) {
// // 判断是否续期token,计算token的过期时间
// long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
// Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
// // 判断当前时间与过期时间的时间差
// long differ = expireDate.getTime() - System.currentTimeMillis();
// // 如果在续期检查的范围内,则续期
// if (differ <= properties.getDetect()) {
// long renew = time + properties.getRenew();
// redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
// }
// }
//
// public String getToken(HttpServletRequest request) {
// String bearerToken = request.getHeader(properties.getHeader());
// if (StringUtils.isBlank(bearerToken)) {
// return null;
// }
// if (bearerToken.startsWith(properties.getTokenStartWith())) {
// // 去掉令牌前缀
// return bearerToken.replace(properties.getTokenStartWith(), "");
// } else {
// log.debug("非法Token:{}", bearerToken);
// }
// return null;
// }
//
// }
......@@ -19,6 +19,8 @@ public abstract class BaseCacheKeys {
private static final String RATE_LIMIT = PREFIX + "rate-limit.";
public static final String USER_DATA_MAP_KEY = "USER-LOGIN-DATA";
/**
* 构建app端用户token的缓存key
*
......
package com.zq.common.config.security;/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.zq.common.config.redis.RedisUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author /
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class TokenProvider implements InitializingBean {
private final RedisUtils redisUtils;
private final SecurityProperties properties;
public static final String AUTHORITIES_KEY = "auth";
private static Key key;
private static SignatureAlgorithm signatureAlgorithm;
@Override
public void afterPropertiesSet() {
signatureAlgorithm = SignatureAlgorithm.HS512;
byte[] keyBytes = DatatypeConverter.parseBase64Binary(properties.getBase64Secret());
key = new SecretKeySpec(keyBytes, signatureAlgorithm.getJcaName());
}
public static String createToken(Authentication authentication) {
String authorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
return Jwts.builder()
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, authorities)
.signWith(signatureAlgorithm, key)
// 加入ID确保生成的 Token 都不一致
.setId(IdUtil.simpleUUID())
.compact();
}
public Claims getClaims(String token) {
return Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
.parseClaimsJws(token)
.getBody();
}
public Authentication getAuthentication(String token) {
Claims claims = getClaims(token);
// fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
Object authoritiesStr = claims.get(AUTHORITIES_KEY);
Collection<? extends GrantedAuthority> authorities =
ObjectUtil.isNotEmpty(authoritiesStr) ?
Arrays.stream(authoritiesStr.toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()) : Collections.emptyList();
User principal = new User(claims.getSubject(), "******", authorities);
return new UsernamePasswordAuthenticationToken(principal, token, authorities);
}
/**
* @param token 需要检查的token
*/
public void checkRenewal(String token) {
// 判断是否续期token,计算token的过期时间
long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
// 判断当前时间与过期时间的时间差
long differ = expireDate.getTime() - System.currentTimeMillis();
// 如果在续期检查的范围内,则续期
if (differ <= properties.getDetect()) {
long renew = time + properties.getRenew();
redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
}
}
public String getToken(HttpServletRequest request) {
String bearerToken = request.getHeader(properties.getHeader());
if (StringUtils.isBlank(bearerToken)) {
return null;
}
if (bearerToken.startsWith(properties.getTokenStartWith())) {
// 去掉令牌前缀
return bearerToken.replace(properties.getTokenStartWith(), "");
} else {
log.debug("非法Token:{}", bearerToken);
}
return null;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment