角色&权限
一、角色&权限
二、项目中如何校验角色&权限(通过拦截器)
采用spring原理中面向切面(aop)的思想,该思想的作用是:对某一类对象进行监督和控制
主要实现:1.通过注解接口创建注解(该注解为需要校验)
2.全局拦截器通过判断方法上是否有该注解,没有则放行,不需要校验;否则,则需要校验
2.1 不校验用户在线NotCheckOnline
注解接口统一放置在pojo下的jpa文件中
package cn.kooun.pojo.jpa;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 利用面向切面的思想
* 不校验用户在线注解接口
* @author HuangJingNa
* @date 2019年12月22日 下午4:49:31
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotCheckOnline {
String value() default "abc";
}
2.2 全局拦截器GlobalInterceptor
package cn.kooun.core.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import cn.kooun.service.UserService;
/**
* 全局拦截器
* @author HuangJingNa
* @date 2019年12月22日 下午4:40:45
*
*/
public class GlobalInterceptor implements HandlerInterceptor{
@Autowired
private UserService userService;
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
if(handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
return baseHandler(request, response, handlerMethod);
}
return true;
}
private boolean baseHandler(
HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) {
boolean flag = true;
flag = userService.checkOnline(request, response, handlerMethod);
if(!flag) {
return flag;
}
flag = userService.checkRoles(request, response, handlerMethod);
if(!flag) {
return flag;
}
flag = userService.checkPerssions(request, response, handlerMethod);
if(!flag) {
return flag;
}
return flag;
}
}
2.3 service层的checkOnline()方法
/**
* 校验是否在线
* @author HuangJingNa
* @date 2019年12月22日 下午4:48:13
*
* @param request
* @param response
* @param handlerMethod
* @return
*/
public boolean checkOnline(
HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) {
//获取方法上的注解,判断是否要进行校验
NotCheckOnline notCheckOnline = handlerMethod.getMethodAnnotation(NotCheckOnline.class);
if(notCheckOnline != null) {
//放行,不进行校验
return true;
}
//获取在线用户
Object user = RequestUtils.getUserLogin(request, response, redisService);
if(user == null) {
ResponseUtils.returnJson(
response,
ResultUtils.error("登录失效,请重新登录~", Result.JUMP_LOGIN));
return false;
}
return true;
}
2.4RequestUtils请求工具类
package cn.kooun.common.request;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.StringUtils;
import cn.kooun.common.redis.RedisService;
import cn.kooun.pojo.info.Dict;
/**
* 请求工具类
* @author HuangJingNa
* @date 2019年12月22日 下午4:52:10
*
*/
public class RequestUtils {
/**
* 校验用户是否在线(根据用户凭证)
* @author HuangJingNa
* @date 2019年12月22日 下午5:03:40
*
* @param request
* @param response
* @param redisService
* @return
*/
public static Object getUserLogin(
HttpServletRequest request,
HttpServletResponse response,
RedisService redisService) {
//登录校验
String userToken = request.getHeader(Dict.USER_TOKEN);
if(StringUtils.isEmpty(userToken)) {
return null;
}
//返回在线数据
return redisService.get(userToken);
}
}
2.5 ResponseUtils响应工具类
package cn.kooun.common.reponse;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import cn.kooun.pojo.info.Dict;
/**
* 响应工具类
* @author HuangJingNa
* @date 2019年12月22日 下午4:52:24
*
*/
public class ResponseUtils {
/**
* response响应json数据格式
*
* @author chenwei
* @date 2018年12月11日 下午5:42:44
* @param response
* @param result
*/
public static void returnJson(HttpServletResponse response, Object result) {
//创建json转换的类
PrintWriter writer = null;
try {
// 避免乱码
response.setCharacterEncoding(Dict.UTF8);
// 设置ContentType
response.setContentType(Dict.JSON_HEAD);
writer = response.getWriter();
writer.append(JSON.toJSONString(result));
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
if(writer!=null) {
writer.close();
}
}
}
}
2.6 数据字典接口Dict
package cn.kooun.pojo.info;
/**
* 数据字典接口
* @author HuangJingNa
* @date 2019年12月22日 下午4:07:46
*
*/
public interface Dict {
/**用户登录凭证*/
String USER_TOKEN = "Token";
/**编码格式设置*/
String UTF8 = "utf-8";
/**Content-Type设置 响应json数据*/
String JSON_HEAD = "application/json; charset=utf-8";
}
三、校验角色&权限
3.1 角色/权限注解接口
package cn.kooun.pojo.jpa;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 角色校验注解接口
* @author HuangJingNa
* @date 2019年12月22日 下午5:15:24
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckRoles {
/**角色数组*/
String[] value();
}
package cn.kooun.pojo.jpa;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限校验注解接口
* @author HuangJingNa
* @date 2019年12月22日 下午5:15:24
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPerssions {
/**权限数组*/
String[] value();
}
3.2 service层中的方法
/**
* 角色校验
* @author HuangJingNa
* @date 2019年12月22日 下午5:19:26
*
* @param request
* @param response
* @param handlerMethod
* @return
*/
public boolean checkRoles(
HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) {
CheckRoles checkRoles = handlerMethod.getMethodAnnotation(CheckRoles.class);
if(checkRoles == null) {
return true;
}
//通过注解获取需要校验的角色标签
List<String> targetRoles = Arrays.asList(checkRoles.value());
//进行角色校验(需要用户在线)
LoginUser user = (LoginUser)
RequestUtils.getUserLogin(request, response, redisService);
List<String> roles = user.getRoles();
//不包含目标角色则拦截
if(!roles.containsAll(targetRoles)) {
ResponseUtils.returnJson(
response,
ResultUtils.error("你没有访问的权限~"));
return false;
}
return true;
}
/**
* 权限校验
* @author HuangJingNa
* @date 2019年12月22日 下午5:29:17
*
* @param request
* @param response
* @param handlerMethod
* @return
*/
public boolean checkPerssions(
HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) {
//获取方法上的注解
CheckPerssions checkPerssions =
handlerMethod.getMethodAnnotation(CheckPerssions.class);
//没有权限注解,放行
if(checkPerssions == null) {
return true;
}
//有,判断用户是否在线
//在线,获取用户所有的权限
LoginUser user = (LoginUser) RequestUtils.getUserLogin(
request, response, redisService);
List<String> permissions = user.getPermissions();
//获取注解上的权限
List<String> targetPerssions = Arrays.asList(checkPerssions.value());
//判断注解上的权限是否包含在用户权限中
//不包含,拦截
if(!permissions.containsAll(targetPerssions)) {
ResponseUtils.returnJson(
response,
ResultUtils.error("你没有访问的权限~"));
return false;
}
return true;
}
3.3 响应结果工具类ResultUtils
package cn.kooun.common.result;
import cn.kooun.common.factory.ErrorFactory;
import cn.kooun.common.factory.SuccessFactory;
/**
* 响应结果工具类
* @author HuangJingNa
* @date 2019年12月22日 下午2:02:04
*
*/
public class ResultUtils {
public static Object success(String message) {
return successCommon(message, null, null);
}
public static Object success(Object result) {
return successCommon(null, result, null);
}
public static Object success(String message, String jump) {
return successCommon(message, null, jump);
}
public static Object success(String message, Object result, String jump) {
return successCommon(message, result, jump);
}
public static Object error(String message, String jump) {
return errorCommon(message, null, jump);
}
public static Object error(String message) {
return errorCommon(message, null, null);
}
/**
* 正确响应公共类
* @author HuangJingNa
* @date 2019年12月22日 下午2:19:35
*
* @param message
* @param result
* @param jump
* @return
*/
private static Object successCommon(String message,Object result,String jump) {
SuccessResult successResult = SuccessFactory.getInstance();
successResult.setMessage(message);
successResult.setResult(result);
successResult.setJump(jump);
return successResult;
}
/**
* 错误响应公共类
* @author HuangJingNa
* @date 2019年12月22日 下午2:19:13
*
* @param message
* @param result
* @param jump
* @return
*/
private static Object errorCommon(String message,Object result,String jump) {
ErrorResult errorResult = ErrorFactory.getInstance();
errorResult.setMessage(message);
errorResult.setResult(result);
errorResult.setJump(jump);
return errorResult;
}
}
以上ResultUtils详情可点击链接 https://www.cnblogs.com/nadou/p/14000976.html