SpringBoot自定义权限控制实现

1、全局拦截前端接口请求
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.mollen.exam.interceptor.UserAuthorityInterceptor;

@Configuration
public class SecurityConfiguration extends WebMvcConfigurerAdapter {

	//自定义拦截器
	@Autowired
	private UserAuthorityInterceptor userAuthorityInterceptor;

	//用户权限拦截器配置
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(userAuthorityInterceptor).addPathPatterns("/**");
	}
}
2.配置无需拦截的接口
/**
*Model:无需拦截器拦截的请求
*Description:无需拦截器拦截的请求
*Author: mollen
*created:2019年8月26日
 */
import java.util.ArrayList;
import java.util.List;

public enum UnFilterURL {

    USER_LOGIN("loginByPwd", "用户登录"),
    USER_LOGIN_OUT("loginOut", "用户登出"),
    USER_UPDATE_PASSWORDS("updatePasswords", "修改密码"),
    USER_FORGET_PASSWORDS("forgetPasswords", "忘记密码"),
    GET_ORG_BY_ACCOUNT_NO("getOrgByAccountNo", "获取管理员机构列表"),
	GET_VALIDATE_CODE("getValidateCode", "获取验证码"),
	   
    UnFilterURL(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public static List<String> getUnFilterList() {
        UnFilterURL[] urls = UnFilterURL.values();
        List<String> unFilterList = new ArrayList<String>();
        for (UnFilterURL ufu : urls) {
            unFilterList.add(ufu.getCode());
        }
        return unFilterList;
    }
    
    //状态码
    private String code;
    
    //描述
    private String desc;

    public String getCode() {
        return code;
    }
    
    public String getDesc() {
        return desc;
    }

}

3.自定义权限接口注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
*Model:AuthAnnotation.java
*Description:自定义权限接口注解
*Author: mollen
*created:2019年8月26日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) //方法声明
public @interface AuthAnnotation {
    /**
     * 请求action
     * @return
     */
	String action();
	/**
	 * 参数,默认空
	 * @return
	 */
	String[] param() default {};
	/**
	 * 是否使用参数 默认false
	 * @return
	 */
	boolean useParam() default false;
}

4.过滤接口
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bojun.author.AuthAnnotation;
import com.bojun.enums.ResponseCodeEnum;

import com.bojun.mollen.entity.dto.SysManageUserDTO;
import com.bojun.mollen.enums.UnFilterURL;
import com.bojun.mollen.service.ISysRoleService;

import com.whalin.MemCached.MemCachedClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
*Model:用户权限拦截器
*Description:用户权限拦截器
*Author: mollen
*created:2019年8月26日
 */
@Component
public class UserAuthorityInterceptor extends HandlerInterceptorAdapter {

	private Log log = LogFactory.getLog(UserAuthorityInterceptor.class);

	//角色业务接口
 	@Autowired
 	private ISysRoleService roleService;

	//MemCached缓存工具
	@Autowired
	private MemCachedClient memCached;

	//controller处理前调用
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
				
		log.info("--------------自定义拦截器----------------");
		System.out.println(handler+"..........");
		
		if (null == handler) {
			return true;
		}
		
		if(!(handler instanceof HandlerMethod)){
			return true;
		}
		
		//方法处理器
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		String actionName = handlerMethod.getMethod().getName();
		List<String> unFilterURLList = UnFilterURL.getUnFilterList();
		
		// 无需权限过滤的URL
		if (unFilterURLList.contains(actionName)) {
			return true;
		}

		// 登录判断
		String token = request.getHeader("token");
		log.info("--------------token----------------:" + token);
		
		JSONObject json = new JSONObject();
		if (StringUtils.isBlank(token)) {
			json.put("code", 401);
			json.put("msg", "超时请登录!");
			outString(response, JSON.toJSONString(json));
			return false;
		}

		// 根据token获取缓存信息
		if (null == memCached.get(token)) {
			json.put("code", 401);
			json.put("msg", "超时请登录!");
			outString(response, JSON.toJSONString(json));
			return false;
		}
		
		//获取用户对象信息
		String valStr = JSON.toJSONString(memCached.get(token));
		SysManageUserDTO manageUser = JSON.parseObject(valStr, SysManageUserDTO.class);

		// 超级管理不用过滤权限
		if (null != manageUser.getType() && 0 == manageUser.getType()) {
			memCached.set(token, manageUser, new Date(15 * 60 * 1000));
			request.setAttribute("manageUser", manageUser);
			return true;
		}
		/**********************接口权限控制****************************/
		String authority = null;
		try {
			//自定义注解找方法
			authority = handlerMethod.getMethodAnnotation(AuthAnnotation.class).action();
		} catch (Exception e) {
			log.error("找不到权限注解方法异常", e);
		}
		
		//方法为空的情况
		if (StringUtils.isEmpty(authority)) {
			json.put("code", "400");
			json.put("msg", "拦截器找不到方法异常");
			outString(response, JSON.toJSONString(json));
			return false;
		}

		// 获取用户权限列表()
		if (StringUtils.isNotEmpty(manageUser.getRoleId())) {
			Map<String, Object> paramsMap = new HashMap<String, Object>();
			paramsMap.put("accountNo", manageUser.getAccountNo());
			//根据账号找菜单
			List<String> authorityMenu = roleService.getLoginAuthorityUrl(paramsMap);
			//菜单为空或者为"common"提示无权限
			if (null == authorityMenu || (!authorityMenu.contains(authority) && !"common".equals(authority))) {
				json.put("code", "403");
				json.put("msg", "暂无访问权限");
				outString(response, JSON.toJSONString(json));
				return false;
			}
		}else{
			json.put("code", "403");
			json.put("msg", "账户未分配角色");
			outString(response, JSON.toJSONString(json));
			return false;
		}

		/****************************************************************/

		memCached.set(token, manageUser, new Date(15 * 60 * 1000));
		request.setAttribute("manageUser", manageUser);
		return true;
	}

	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {

	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {

	}

	/**
	 * 将字符串转换成JSON字符串发送
	 * @param str
	 */
	public void outString(HttpServletResponse response, String str) {
		try {
			response.setCharacterEncoding("UTF-8");
			PrintWriter out = response.getWriter();
			out.write(str);
			out.flush();
			out.close();
		} catch (IOException e) {
			log.error(e);
		}
	}
	
}
5.使用方式
  /**
     * @Description:  分页查询用户
     * @Author: mollen
     * @create: 2019/6/28  13:48
     *
     */
    @RequestMapping(value = "/getAllByCondition", method = RequestMethod.POST)
    //@AuthAnnotation(action = "common")							//放行注解
    //@AuthAnnotation(action = "manageUser:getAllByCondition")		//控制注解
    public  void  getAllByCondition(HttpServletRequest request,
                                    @RequestParam(value = "pageNum") int pageNum,
                                    @RequestParam(value = "pageSize") int pageSize){
        try {
        
         //业务代码
        	...
         
        } catch (Exception e) {
            log.error("getAllByCondition:", e);
            outJson(errorInfo(ResponseCodeEnum.EXCEPTION_REQUEST.getCode()));
        }
    }
6.总结
1.自定义适配器
继承WebMvcConfigurerAdapter类重写addInterceptors()方法拦截所有接口。(Spring5 要用WebMvcConfigurer)
2.自定义拦截规则
继承HandlerInterceptorAdapter类,重写preHandle()方法。
3.枚举不过滤接口。
4.自定义权限控制注解。
拦截器通过handlerMethod.getMethodAnnotation(AuthAnnotation.class).action()拿到这个注解里面的值判断是否有接口权限。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值