java登录权限实现
分享一个简单java的登录权限实现过程吧,复制即用我这里是用拦截器实现的,使用的redis,springboot2。废话不多说,上代码吧定义验证等级枚举:public enumAuthorityType {//不验证Nocheck,//只验证登录CheckLongin,// 登录和权限都验证CheckLevel0,//用户等级为0权限CheckLevel1,//用户等级为1权限CheckLevel
·
分享一个简单java的登录权限实现过程吧,复制即用
我这里是用拦截器实现的,使用的redis,springboot2。废话不多说,上代码吧
定义验证等级枚举:
public enum AuthorityType {
//不验证
Nocheck,
//只验证登录
CheckLongin,
// 登录和权限都验证
CheckLevel0,//用户等级为0权限
CheckLevel1,//用户等级为1权限
CheckLevel2,//用户等级为2权限
}
定义接口:
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authority {
// 默认验证
AuthorityType value() default AuthorityType.Nocheck;
}
定义拦截器:
//登录权限验证拦截器
@Slf4j
@Aspect
@Component
public class AuthorityAnnotationInterceptor extends HandlerInterceptorAdapter {
//redis注入
@Autowired
private StringRedisTemplate redisTemplate;
//用户业务层接口
@Autowired
private IWjUserService wjUserService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
Class<?> clazz = hm.getBeanType();
Method m = hm.getMethod();
try {
if (clazz != null && m != null) {
boolean isClzAnnotation = clazz.isAnnotationPresent(Authority.class);
boolean isMethondAnnotation = m.isAnnotationPresent(Authority.class);
Authority authority = null;
// 如果方法和类声明中同时存在这个注解,那么方法中的会覆盖类中的设定。
//方法上的@Authority注解优先级比类高
if (isMethondAnnotation) {
authority = m.getAnnotation(Authority.class);
} else if (isClzAnnotation) {
authority = clazz.getAnnotation(Authority.class);
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
if (authority != null) {
if (AuthorityType.Nocheck == authority.value()) {
// 标记为不验证,放行
return true;
} else{
//验证登录
//encrytestr 为用户登录生成的一个标识,由userId和userToken加密得来的,登录后将encrytestr存于redis中,登录后将encrytestr返回前端,前端将其作为公共参数放入请求头
//获取请求头中的encrytestr
String encrytestr = request.getHeader("encrytestr");//获取encrytestr
if(StringUtils.isBlank(encrytestr)){
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token过期,请重新登录")));
return false;
}
//从redis中查找encrytestr存不存在
String userString = redisTemplate.opsForValue().get("ulogin"+encrytestr);
System.out.println(userString);
if(StringUtils.isBlank(userString)){
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token过期,请重新登录")));
return false;
}
//将encrytestr进行解密得到token和userid
Map<String, String> map = CommenUtils.decryptUserIdAndTokenByStr(encrytestr);
String token = map.get("token");
String userId = map.get("userId");
if(StringUtils.isBlank(token)||StringUtils.isBlank(userId)){
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token错误")));
return false;
}
WjUser wju = this.wjUserService.getById(userId);
if (wju == null) {
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token错误")));
return false;
}
//验证用户token是否过期
if (!wju.getToken().equals(token)) {
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"token过期,请重新登录")));
return false;
}
if (AuthorityType.CheckLongin == authority.value()) {
// 不验证权限,验证是否登录
// TODO:
return true;
}else{
//验证用户等级
if (AuthorityType.CheckLevel0 == authority.value()) {
// 不验证权限,验证是否登录
// TODO:
if(wju.getLevel()!=0){
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
return false;
}
return true;
}else if (AuthorityType.CheckLevel1 == authority.value()) {
// 不验证权限,验证是否登录
// TODO:
if(wju.getLevel()!=1){
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
return false;
}
return true;
}else if (AuthorityType.CheckLevel2 == authority.value()) {
// 不验证权限,验证是否登录
// TODO:
if(wju.getLevel()!=2){
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
return false;
}
return true;
} else {
// 验证登录及权限
// TODO:
//response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限不符")));
return true;
}
}
}
}
// 未通过验证,返回提示json
/*
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限错误")));*/
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
response.getWriter().write(JSON.toJSONString(new AjaxResult(StatusCode.ERROR_CODE_40000,"权限错误")));*/
return true;
}
}
配置拦截器:
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Autowired
AuthorityAnnotationInterceptor authorityAnnotationInterceptor;
@Override //拦截器配置
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorityAnnotationInterceptor) //拦截器注册对象
.addPathPatterns("/**") //指定要拦截的请求
.excludePathPatterns("/wjUser/loginUser"); //排除请求
}
}
登录成功之后:
String aesKey = "fd980019fc95df40f0ed43731a11219f";
//生成userToken,并将token和userid加密成encryptStr,存于redis中
String key = "ulogin";
if(redisTemplate.hasKey(key+getuser.getEncrytestr())){
redisTemplate.delete(key+getuser.getEncrytestr());
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(new Date());
String token = CommenUtils.jdkAESEncrypt(aesKey, format + "," + getuser.getUseraccount());
getuser.setToken(token);
String encrypt = CommenUtils.encryptGameUserIdAndToken(getuser.getId(), getuser.getToken());
getuser.setEncrytestr(encrypt);
getuser.setLastlogintime(new Timestamp(System.currentTimeMillis()));
wjUserService.updateById(getuser);
getuser.setPassword("");
redisTemplate.opsForValue().set(key+getuser.getEncrytestr(), JSON.toJSONString(getuser),60 * 60 * 24, TimeUnit.SECONDS);
return new AjaxResult(getuser,"登录成功");
工具类里的一些代码:
@Slf4j
public class CommenUtils {
public static Map<String,String> decryptUserIdAndTokenByStr(String encryptStr) {
String gameAesKey = "Ae980019bc59fd40f0ef34798e11210a";
String decryptStr = CommenUtils.jdkAESDecrypt(gameAesKey, encryptStr);
// log.info("游戏token解密完的字符串:"+decryptStr);
Map<String,String> map = new HashMap<>();
String[] split = decryptStr.split(",");
if (split.length != 2){
return null;
}
map.put("userId",split[0]);
map.put("token",split[1]);
return map;
}
/*
* AES加密
* @prama HexStringkey 密钥
* @prama content 加密的内容
* */
public static String jdkAESEncrypt(String HexStringkey,String content) {
try {
byte[] byteskey = Hex.decodeHex(HexStringkey.toCharArray());
//转换key
Key convertSecretKey = new SecretKeySpec(byteskey, "AES");
//加密
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
byte[] encryptResult = cipher.doFinal(content.getBytes());
String encryptResultStr = Hex.encodeHexString(encryptResult);
log.info("jdk des encrypt:" + encryptResultStr);
return encryptResultStr;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static String encryptGameUserIdAndToken(String userId,String token) {
String gameAesKey = "Ae980019bc59fd40f0ef34798e11210a";
System.out.println("123123");
System.out.println(gameAesKey);
System.out.println(userId);
System.out.println(token);
String encryptStr = CommenUtils.jdkAESEncrypt(gameAesKey, userId+","+token);
return encryptStr;
}
/*
* AES解密
* @prama HexStringkey 密钥
* @prama encryptResultStr 解密的内容
* */
public static String jdkAESDecrypt(String HexStringkey,String encryptResultStr) {
try {
byte[] byteskey = Hex.decodeHex(HexStringkey.toCharArray());
//转换key
Key convertSecretKey = new SecretKeySpec(byteskey, "AES");
// 解密
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
byte[] encryptResult = Hex.decodeHex(encryptResultStr.toCharArray());
byte[] decryptResult = cipher.doFinal(encryptResult);
String decryptStr = new String(decryptResult);
log.info("jdk des decrypt:" + decryptStr);
return decryptStr;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
使用的时候就直接在方法上@Authority(AuthorityType.CheckLevel0)就可以
在控制器内也可以获取用户id
String encrytestr = request.getHeader("encrytestr");
//token过期验证
Map<String, String> map = CommenUtils.decryptUserIdAndTokenByStr(encrytestr);
String userId = map.get("userId");
WjUser wju = this.wjUserService.getById(userId);
分享差不多就结束了,复制的话需要将用户换成你们自己的,我这里权限验证只是分了个等级,大家可以根据自己的需求自行更改,代码还不是很完善,大家有什么问题和建议可以在评论留言。
感谢大家的阅读
更多推荐
已为社区贡献4条内容
所有评论(0)