权限校验
This commit is contained in:
parent
36cc4f8b4e
commit
5c38e54fbd
@ -0,0 +1,53 @@
|
||||
package cn.com.tenlion.accesstokenmanager;
|
||||
|
||||
|
||||
import cn.com.tenlion.pojo.dtos.carduser.CardUserDTO;
|
||||
import cn.com.tenlion.pojo.vos.carduser.CardUserVO;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @version 1.0
|
||||
* @author LY
|
||||
* @date 2021/1/27 11:00
|
||||
*/
|
||||
public class AccessTokenManager {
|
||||
|
||||
private static Map<String, CardUserDTO> cardUserVOMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private AccessTokenManager(){
|
||||
|
||||
}
|
||||
|
||||
public static AccessTokenManager getInstance(){
|
||||
return tokenManageBuiler.accessTokenInstance;
|
||||
}
|
||||
|
||||
|
||||
public CardUserDTO getKey(String key){
|
||||
return cardUserVOMap.get(key);
|
||||
}
|
||||
|
||||
public void setKey(String key,CardUserDTO cardUserDTO){
|
||||
cardUserVOMap.put(key,cardUserDTO);
|
||||
}
|
||||
|
||||
public void removeKey(String key){
|
||||
cardUserVOMap.remove(key);
|
||||
}
|
||||
|
||||
|
||||
public void updateLastActivityTime(String key){
|
||||
CardUserDTO dto = this.getKey(key);
|
||||
dto.setLastActivityTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
private static class tokenManageBuiler{
|
||||
private static AccessTokenManager accessTokenInstance = new AccessTokenManager();
|
||||
}
|
||||
|
||||
}
|
88
src/main/java/cn/com/tenlion/config/CheckAuth.java
Normal file
88
src/main/java/cn/com/tenlion/config/CheckAuth.java
Normal file
@ -0,0 +1,88 @@
|
||||
package cn.com.tenlion.config;
|
||||
|
||||
|
||||
import cn.com.tenlion.accesstokenmanager.AccessTokenManager;
|
||||
import cn.com.tenlion.pojo.dtos.carduser.CardUserDTO;
|
||||
import cn.com.tenlion.pojo.vos.carduser.CardUserVO;
|
||||
import cn.com.tenlion.service.carduser.ICardUserService;
|
||||
import cn.com.tenlion.util.AesUtil;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @version 1.0
|
||||
* @author LY
|
||||
* @date 2021/1/27 12:20
|
||||
*/
|
||||
@Component
|
||||
public class CheckAuth implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
private ICardUserService cardUserService;
|
||||
|
||||
/**
|
||||
* 在请求处理之前进行调用(Controller方法调用之前)
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
try {
|
||||
String path = request.getServletPath();
|
||||
if(path.contains("release")){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
String token = request.getHeader("token");
|
||||
if(token == null || StringUtil.isEmpty(token)){
|
||||
// response.setStatus(response.SC_METHOD_NOT_ALLOWED);
|
||||
// response.addHeader("msg","token不合法");
|
||||
response.sendError(response.SC_METHOD_NOT_ALLOWED,"token不合法");
|
||||
return false;
|
||||
}
|
||||
|
||||
CardUserDTO tokenManage = AccessTokenManager.getInstance().getKey(token);
|
||||
if(tokenManage != null) {
|
||||
AccessTokenManager.getInstance().updateLastActivityTime(token);
|
||||
return true;
|
||||
}else{
|
||||
String aesDecoderToken = AesUtil.aesCommonDecoder(token,token);
|
||||
CardUserDTO cardUserDTO = cardUserService.getCardUserById(aesDecoderToken);
|
||||
if(cardUserDTO != null){
|
||||
AccessTokenManager.getInstance().setKey(token,cardUserDTO);
|
||||
AccessTokenManager.getInstance().updateLastActivityTime(token);
|
||||
}
|
||||
}
|
||||
response.setStatus(response.SC_OK);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
|
||||
*/
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
|
||||
System.out.println("执行了TestInterceptor的postHandle方法");
|
||||
}
|
||||
|
||||
/**
|
||||
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
System.out.println("执行了TestInterceptor的afterCompletion方法");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
31
src/main/java/cn/com/tenlion/config/LoginConfig.java
Normal file
31
src/main/java/cn/com/tenlion/config/LoginConfig.java
Normal file
@ -0,0 +1,31 @@
|
||||
package cn.com.tenlion.config;
|
||||
|
||||
import org.apache.catalina.startup.UserConfig;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* 拦截器初始化
|
||||
* @version 1.0
|
||||
* @author LY
|
||||
* @date 2021/1/27 12:34
|
||||
*/
|
||||
@Configuration
|
||||
public class LoginConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
//注册TestInterceptor拦截器
|
||||
InterceptorRegistration registration = registry.addInterceptor(checkAuth());
|
||||
registration.addPathPatterns("/app/**"); //app所有路径都被拦截
|
||||
}
|
||||
|
||||
@Bean
|
||||
private static CheckAuth checkAuth() {
|
||||
return new CheckAuth();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package cn.com.tenlion.pojo.dtos.weixinresult;
|
||||
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @version 1.0
|
||||
* @author LY
|
||||
* @date 2021/1/26 16:45
|
||||
*/
|
||||
public class WeiXinAuthResult {
|
||||
/**用户唯一标识*/
|
||||
private String openid;
|
||||
/**会话密钥*/
|
||||
private String session_key;
|
||||
/**用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回*/
|
||||
private String unionid;
|
||||
/**错误码*/
|
||||
private String errcode;
|
||||
/**错误信息*/
|
||||
private String errmsg;
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
public String getSession_key() {
|
||||
return session_key;
|
||||
}
|
||||
|
||||
public void setSession_key(String session_key) {
|
||||
this.session_key = session_key;
|
||||
}
|
||||
|
||||
public String getUnionid() {
|
||||
return unionid;
|
||||
}
|
||||
|
||||
public void setUnionid(String unionid) {
|
||||
this.unionid = unionid;
|
||||
}
|
||||
|
||||
public String getErrcode() {
|
||||
return errcode;
|
||||
}
|
||||
|
||||
public void setErrcode(String errcode) {
|
||||
this.errcode = errcode;
|
||||
}
|
||||
|
||||
public String getErrmsg() {
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
public void setErrmsg(String errmsg) {
|
||||
this.errmsg = errmsg;
|
||||
}
|
||||
}
|
155
src/main/java/cn/com/tenlion/util/AesUtil.java
Normal file
155
src/main/java/cn/com/tenlion/util/AesUtil.java
Normal file
@ -0,0 +1,155 @@
|
||||
package cn.com.tenlion.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.codec.binary.StringUtils;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.*;
|
||||
|
||||
public class AesUtil {
|
||||
|
||||
private static final String IV_STRING = "16-Bytes--String";
|
||||
/**
|
||||
* PKCS#7
|
||||
*/
|
||||
public static final String PKCS_7 = "PKCS7Padding";
|
||||
/**
|
||||
* PKCS#5
|
||||
*/
|
||||
public static final String PKCS_5 = "PKCS5Padding";
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
*
|
||||
* @param encodeRule
|
||||
* @param content
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesEncoder(String encodeRule, String content) throws Exception {
|
||||
// 1.构造秘钥生成器
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
// 2.根据编码规则构建秘钥生成器
|
||||
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||||
random.setSeed(encodeRule.getBytes());
|
||||
keyGenerator.init(128, random);
|
||||
// 3.产生堆成秘钥
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
// 4.对称秘钥原始数组
|
||||
byte[] secretKeyByte = secretKey.getEncoded();
|
||||
// 5.生成AES秘钥
|
||||
SecretKey key = new SecretKeySpec(secretKeyByte, "AES");
|
||||
// 6.初始化密码器
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
// 8.获取加密内容字节数组
|
||||
byte[] contentByte = content.getBytes("UTF-8");
|
||||
// 9.加密
|
||||
return new String(Base64.encodeBase64(cipher.doFinal(contentByte)));
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密
|
||||
*
|
||||
* @param encodeRule
|
||||
* @param content
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesDecoder(String encodeRule, String content) throws Exception {
|
||||
// 1.构建秘钥生成器
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
// 2.根据编码规则构建秘钥生成器
|
||||
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||||
random.setSeed(encodeRule.getBytes());
|
||||
keyGenerator.init(128, random);
|
||||
// 3.生成对称解密秘钥
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
// 4.对称秘钥原始数组
|
||||
byte[] secretKeyByte = secretKey.getEncoded();
|
||||
// 5.生成AES秘钥
|
||||
SecretKey key = new SecretKeySpec(secretKeyByte, "AES");
|
||||
// 6.初始化密码器
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(Cipher.DECRYPT_MODE, key);
|
||||
// 7.要解密内容的字节数组
|
||||
byte[] contentByte = Base64.decodeBase64(content);
|
||||
// 8.解密
|
||||
return new String(cipher.doFinal(contentByte), "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用aes加密,兼容IOS
|
||||
*
|
||||
* @param key
|
||||
* @param content
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesCommonEncoder(String key, String content) throws Exception {
|
||||
byte[] encryptedBytes = aesCommonEncodeDetail(key, content, IV_STRING.getBytes(), PKCS_5);
|
||||
return new String(Base64.encodeBase64(encryptedBytes), "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用aes加密,兼容IOS
|
||||
*
|
||||
* @param key
|
||||
* @param content
|
||||
* @param paddingType
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] aesCommonEncodeDetail(String key, String content, byte[] ivBytes, String paddingType) throws Exception {
|
||||
byte[] byteContent = content.getBytes("UTF-8");
|
||||
byte[] enCodeFormat = key.getBytes();
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
|
||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
|
||||
if (StringUtils.equals(paddingType, PKCS_7)) {
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
}
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/" + paddingType);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
||||
return cipher.doFinal(byteContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* aes通用解密,兼容IOS
|
||||
*
|
||||
* @param key
|
||||
* @param content
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesCommonDecoder(String key, String content) throws Exception {
|
||||
byte[] encryptedBytes = Base64.decodeBase64(content);
|
||||
byte[] keyBytes = key.getBytes();
|
||||
byte[] result = aesCommonDecoderDetail(keyBytes, encryptedBytes, IV_STRING.getBytes(), PKCS_5);
|
||||
return new String(result, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* aes cbc 通用解密
|
||||
*
|
||||
* @param keyBytes 秘钥字节数组
|
||||
* @param encryptedBytes 密文字节数组
|
||||
* @param ivBytes 向量字节数组
|
||||
* @param paddingType 填充类型
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] aesCommonDecoderDetail(byte[] keyBytes, byte[] encryptedBytes, byte[] ivBytes, String paddingType) throws Exception {
|
||||
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
|
||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
|
||||
Cipher cipher;
|
||||
if (StringUtils.equals(paddingType, PKCS_7)) {
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
}
|
||||
cipher = Cipher.getInstance("AES/CBC/" + paddingType);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
|
||||
return cipher.doFinal(encryptedBytes);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.com.tenlion.util.exception;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName: UpdateException
|
||||
* @Description: 编辑异常
|
||||
* @Author: WangGeng
|
||||
* @Date: 2019/2/26 5:25 PM
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class UpdateException extends SystemException {
|
||||
|
||||
public UpdateException() {
|
||||
}
|
||||
|
||||
public UpdateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UpdateException(String message, boolean withMsg) {
|
||||
super(message, withMsg);
|
||||
}
|
||||
|
||||
public UpdateException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public UpdateException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
69
src/main/java/cn/com/tenlion/util/vx/WxApiUtil.java
Normal file
69
src/main/java/cn/com/tenlion/util/vx/WxApiUtil.java
Normal file
@ -0,0 +1,69 @@
|
||||
package cn.com.tenlion.util.vx;
|
||||
|
||||
|
||||
import cn.com.tenlion.pojo.dtos.weixinresult.WeiXinAuthResult;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信相关api
|
||||
* @version 1.0
|
||||
* @author LY
|
||||
* @date 2021/1/27 16:35
|
||||
*/
|
||||
public class WxApiUtil {
|
||||
|
||||
/**微信获取登陆凭证校验 接口*/
|
||||
private static String VX_SMALL_ROUTINE_SESSION_KEY = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
|
||||
|
||||
/**
|
||||
* 获取微信登陆凭证
|
||||
* @param code 登录时获取的 code
|
||||
* @param appId 小程序 appId
|
||||
* @param secret 小程序 appSecret
|
||||
* @param grantType 授权类型,此处只需填写 authorization_code
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public WeiXinAuthResult weiXinLoginGetAuth(String code,String appId,String secret,String grantType) throws Exception{
|
||||
WeiXinAuthResult result = new WeiXinAuthResult();
|
||||
result.setErrcode("1");
|
||||
if(StringUtils.isEmpty(code) && null != code){
|
||||
result.setErrmsg("code 不能为空");
|
||||
return result;
|
||||
}
|
||||
if(StringUtils.isEmpty(appId) && null != appId){
|
||||
result.setErrmsg("appId 不能为空");
|
||||
return result;
|
||||
}
|
||||
if(StringUtils.isEmpty(secret) && null != secret){
|
||||
result.setErrmsg("secret 不能为空");
|
||||
return result;
|
||||
}
|
||||
if(StringUtils.isEmpty(grantType) && null != grantType){
|
||||
result.setErrmsg("grantType不能为空");
|
||||
return result;
|
||||
}
|
||||
// 配置请求参数
|
||||
Map<String, String> param = new HashMap<>();
|
||||
param.put("appid", appId);
|
||||
param.put("secret", secret);
|
||||
param.put("js_code", code);
|
||||
param.put("grant_type", grantType);
|
||||
String str = WxUtil.doGet(VX_SMALL_ROUTINE_SESSION_KEY, param);
|
||||
JSONObject json = JSONObject.parseObject(str);
|
||||
return JSON.toJavaObject(json, WeiXinAuthResult.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user