角色&权限

一、角色&权限

角色&权限.png

二、项目中如何校验角色&权限(通过拦截器)

采用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

原文地址:https://www.cnblogs.com/nadou/p/14003661.html