SpringMVC拦截器+Spring自定义注解实现权限验证

设计思路

主要针对需要登录后操作的接口进行校验。接入层在对外暴露接口后,网页、APP、第三方等等途径进行访问接口。用户请求首先会被SpringMVC拦截器拦截到,在拦截器里第一步就是需要校验用户的登录身份(由于是分布式系统这里采用的是userId+accessToken方式来校验),登录校验通过之后再进行用户权限校验,此时会自动拦截@AuthValidate注解的method(核心),如果权限校验失败则抛出权限不足异常,否则校验通过之后再执行具体接口并返回结果。

1、自定义注解

 1 package com.mao.auth;
 2 import java.lang.annotation.Documented;
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7
 8 /**
 9  *
10  * 项目名称:---
11  * 模块名称:接入层
12  * 功能描述:权限定义
13  * 创建人: [email protected]
14  * 创建时间:2017年5月9日 下午8:41:05
15  * 修改人: [email protected]
16  * 修改时间:2017年5月9日 下午8:41:05
17  */
18 @Target(value = ElementType.METHOD)
19 @Retention(value = RetentionPolicy.RUNTIME)
20 @Documented
21 public @interface AuthValidate {
22
23     /**
24      *
25      * 描述:权限定义
26      * @author [email protected]
27      * @created 2017年5月8日 上午11:36:41
28      * @since
29      * @return 权限代码
30      */
31     AuthCode value() default AuthCode.Allow;
32
33 }

2、权限枚举

  1 package com.mao.auth;
  2
  3 /**
  4  *
  5  * 项目名称:---
  6  * 模块名称:接入层
  7  * 功能描述:权限类型枚举
  8  * 创建人: [email protected]
  9  * 创建时间:2017年5月8日 上午11:43:12
 10  * 修改人: [email protected]
 11  * 修改时间:2017年5月8日 上午11:43:12
 12  */
 13 public enum AuthCode {
 14
 15     Allow("00000", "00000", "允许访问"),
 16
 17     /******************客户权限******************/
 18
 19     AU0001("100001", "AU0001", "新增用户", "新增用户"),
 20
 21     AU0002("100002", "AU0002", "删除用户", "批量删除用户");
 22
 23     /**权限标识 */
 24     private String authId;
 25
 26     /**权限编码 */
 27     private String authCode;
 28
 29     /**权限名称 */
 30     private String authName;
 31
 32     /**权限描述 */
 33     private String authDesc;
 34
 35     /**
 36      *
 37      * 描述:构建设备类型
 38      * @author [email protected]
 39      * @created 2017年3月22日 上午13:50:58
 40      * @since
 41      * @param authId 权限标识
 42      * @param authCode 权限编码
 43      * @param authName 权限名称
 44      * @return
 45      */
 46     private AuthCode(String authId, String authCode, String authName) {
 47         this.authId = authId;
 48         this.authCode = authCode;
 49         this.authName = authName;
 50     }
 51
 52     /**
 53      *
 54      * 描述:构建设备类型
 55      * @author [email protected]
 56      * @created 2017年3月22日 上午13:50:58
 57      * @since
 58      * @param authId 权限标识
 59      * @param authCode 权限编码
 60      * @param authName 权限名称
 61      * @param authDesc 权限描述
 62      * @return
 63      */
 64     private AuthCode(String authId, String authCode, String authName, String authDesc) {
 65         this.authId = authId;
 66         this.authCode = authCode;
 67         this.authName = authName;
 68         this.authDesc = authDesc;
 69     }
 70
 71     public String getAuthId() {
 72         return authId;
 73     }
 74
 75     public void setAuthId(String authId) {
 76         this.authId = authId;
 77     }
 78
 79     public String getAuthCode() {
 80         return authCode;
 81     }
 82
 83     public void setAuthCode(String authCode) {
 84         this.authCode = authCode;
 85     }
 86
 87     public String getAuthDesc() {
 88         return authDesc;
 89     }
 90
 91     public void setAuthDesc(String authDesc) {
 92         this.authDesc = authDesc;
 93     }
 94
 95     public String getAuthName() {
 96         return authName;
 97     }
 98
 99     public void setAuthName(String authName) {
100         this.authName = authName;
101     }
102
103     @Override
104     public String toString() {
105         return String.format("authId:%s, authCode:%s, authName:%s, authDesc:%s", this.authId, this.authCode, this.authName, this.authDesc);
106     }
107
108 }

3、Controller使用自定义注解

 1 package com.mao.controller;
 2
 3 import javax.servlet.http.HttpServletRequest;
 4
 5 import org.apache.commons.logging.Log;
 6 import org.apache.commons.logging.LogFactory;
 7 import org.springframework.stereotype.Controller;
 8 import org.springframework.web.bind.annotation.RequestMapping;
 9 import org.springframework.web.bind.annotation.ResponseBody;
10
11 import com.mao.auth.AuthCode;
12 import com.mao.auth.AuthValidate;
13 import com.mao.beans.ResObject;
14 import com.mao.exception.BusinessException;
15
16 /**
17  *
18  * 项目名称:---
19  * 模块名称:接入层
20  * 功能描述:用户控制层
21  * 创建人: [email protected]
22  * 创建时间:2017年5月9日 下午8:15:50
23  * 修改人: [email protected]
24  * 修改时间:2017年5月9日 下午8:15:50
25  */
26 @Controller
27 @RequestMapping("/userController")
28 public class UserController {
29
30     /**日志*/
31     @SuppressWarnings("unused")
32     private static final Log loger = LogFactory.getLog(UserController.class);
33
34      /**
35       *
36       * 描述:新增用户
37       * @author [email protected]
38       * @created 2017年5月9日 下午8:16:41
39       * @since
40       * @param request
41       * @return
42       * @throws BusinessException
43       */
44     @RequestMapping("/createUser")
45     @ResponseBody
46     @AuthValidate(AuthCode.AU0001)
47     public ResObject createUser(HttpServletRequest request) throws BusinessException{
48         //业务代码
49         return new ResObject();
50     }
51
52     /**
53       *
54       * 描述:新增用户
55       * @author [email protected]
56       * @created 2017年5月9日 下午8:16:41
57       * @since
58       * @param request
59       * @return
60       * @throws BusinessException
61       */
62     @RequestMapping("/deleteUser")
63     @ResponseBody
64     @AuthValidate(AuthCode.AU0002)
65     public ResObject deleteUser(HttpServletRequest request) throws BusinessException{
66         //业务代码
67         return new ResObject();
68     }
69 }

4、SpringMVC拦截器

  1 package com.mao.interceptor;
  2 import java.io.PrintWriter;
  3 import java.util.ArrayList;
  4 import java.util.List;
  5
  6 import javax.servlet.http.HttpServletRequest;
  7 import javax.servlet.http.HttpServletResponse;
  8
  9 import org.springframework.web.method.HandlerMethod;
 10 import org.springframework.web.servlet.HandlerInterceptor;
 11 import org.springframework.web.servlet.ModelAndView;
 12
 13 import com.mao.auth.AuthCode;
 14 import com.mao.auth.AuthValidate;
 15 import com.mao.exception.BusinessException;
 16 import com.mao.util.JsonUtil;
 17
 18 /**
 19  *
 20  * 项目名称:---
 21  * 模块名称:接入层
 22  * 功能描述:用户登录拦截器(利用SpringMVC自定义拦截器实现)
 23  * 创建人: [email protected]
 24  * 创建时间:2017年4月25日 下午8:53:49
 25  * 修改人: [email protected]
 26  * 修改时间:2017年4月25日 下午8:53:49
 27  */
 28 public class UserLoginInterceptor implements HandlerInterceptor {
 29
 30     /**
 31      *
 32      * 描述:构造函数
 33      * @author [email protected]
 34      * @created 2017年4月28日 下午5:20:34
 35      * @since
 36      * @param accessService
 37      */
 38     public UserLoginInterceptor() {
 39
 40     }
 41
 42     /**
 43      *
 44      * 描述:执行方法前
 45      * @author [email protected]
 46      * @created 2017年4月25日 下午9:01:44
 47      * @since
 48      * @param request HttpServletRequest
 49      * @param response HttpServletResponse
 50      * @param handler handler
 51      * @return
 52      * @throws Exception
 53      */
 54     @Override
 55     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 56         try {
 57             //校验登录
 58             this.userLoginValidate(request);
 59             //校验权限
 60             this.userAuthValidate(request, handler);
 61         } catch (Exception e) {
 62             e.printStackTrace();
 63             printMessage(response, e);
 64             return false;
 65         }
 66         return true;
 67     }
 68
 69     /**
 70      *
 71      * 描述:输出到前端
 72      * @author [email protected]
 73      * @created 2017年4月28日 上午11:00:25
 74      * @since
 75      * @param response 响应
 76      * @param res 对象
 77      * @throws Exception
 78      */
 79     public static void printMessage(HttpServletResponse response, Object res) throws Exception{
 80         PrintWriter writer = null;
 81         response.setCharacterEncoding("UTF-8");
 82         response.setContentType("text/html; charset=utf-8");
 83         try {
 84             writer = response.getWriter();
 85             writer.print(JsonUtil.toJson(res));
 86         } catch (Exception e) {
 87             e.printStackTrace();
 88         } finally {
 89             if (writer != null){
 90                 writer.close();
 91             }
 92         }
 93     }
 94
 95     @Override
 96     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
 97
 98     }
 99
100     @Override
101     public void afterCompletion(HttpServletRequest request,    HttpServletResponse response, Object handler, Exception ex)    throws Exception {
102
103     }
104
105     /**
106      *
107      * 描述:用户登录校验
108      * @author [email protected]
109      * @created 2017年5月9日 下午8:27:25
110      * @since
111      * @param request
112      * @throws BusinessException
113      */
114     private void userLoginValidate(HttpServletRequest request) throws BusinessException {
115         //校验代码
116     }
117
118     /**
119      *
120      * 描述:用户权限校验
121      * @author [email protected]
122      * @created 2017年5月4日 下午8:34:09
123      * @since
124      * @param request HttpServletRequest
125      * @param handler
126      * @return
127      * @throws BusinessException
128      */
129     private void userAuthValidate(HttpServletRequest request, Object handler) throws BusinessException {
130         AuthValidate validate = ((HandlerMethod) handler).getMethodAnnotation(AuthValidate.class);
131         if(validate == null){
132             throw new BusinessException("未配置自定义注解");
133         }
134         String funcCode = validate.value().getAuthCode();
135         if(funcCode.equals(AuthCode.Allow.getAuthCode())){
136             return;
137         }
138         String authId = validate.value().getAuthId();
139         List<String> auths = new ArrayList<>();//模拟从缓存或者从数据库中查询出对应用户的权限
140         if(!auths.contains(authId)){
141             throw new BusinessException("权限不足");
142         }
143     }
144
145 }

5、拦截器配置

 1 package com.mao.interceptor;
 2
 3 import org.apache.commons.logging.Log;
 4 import org.apache.commons.logging.LogFactory;
 5 import org.springframework.context.annotation.ComponentScan;
 6 import org.springframework.context.annotation.Configuration;
 7 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 8 import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
 9 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
10 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
11
12 /**
13  *
14  * 项目名称:---
15  * 模块名称:接入层
16  * 功能描述:拦截器配置
17  * 创建人: [email protected]
18  * 创建时间:2017年5月9日 下午8:54:00
19  * 修改人: [email protected]
20  * 修改时间:2017年5月9日 下午8:54:00
21  */
22 @Configuration
23 @ComponentScan(basePackages={"com.mao"})
24 @EnableWebMvc
25 public class WebConfiguration extends WebMvcConfigurerAdapter {
26
27     /**日志*/
28     private static final Log loger = LogFactory.getLog(WebConfiguration.class);
29
30     /**
31      *
32      * 描述:构造函数
33      * @author [email protected]
34      * @created 2017年5月3日 下午4:48:41
35      * @since
36      */
37     public WebConfiguration() {
38         loger.info("开启系统登录拦截");
39     }
40
41     /**
42      *
43      * 描述:添加拦截器
44      * @author [email protected]sina.com
45      * @created 2017年4月25日 下午8:50:54
46      * @since
47      * @param registry
48      */
49     @Override
50     public void addInterceptors(InterceptorRegistry registry) {
51         this.excludeUserLogin(registry.addInterceptor(new UserLoginInterceptor()));
52     }
53
54     /**
55      *
56      * 描述:拦截请求
57      * @author [email protected]
58      * @created 2017年5月9日 下午8:55:28
59      * @since
60      * @param registration
61      */
62     public void excludeUserLogin(InterceptorRegistration registration){
63         registration.addPathPatterns("/userController/*");
64     }
65
66 }

6、返回对象

  1 package com.mao.beans;
  2
  3 import java.io.Serializable;
  4
  5 /**
  6  *
  7  * 项目名称:
  8  * 模块名称:
  9  * 功能描述:
 10  * 创建人: [email protected]
 11  * 创建时间:2017年5月3日 下午6:37:11
 12  * 修改人: [email protected]
 13  * 修改时间:2017年5月3日 下午6:37:11
 14  */
 15 public class ResObject implements Serializable{
 16
 17     /**序列号*/
 18     private static final long serialVersionUID = 589903502110209046L;
 19
 20     /**返回代码*/
 21     private int code = 200;
 22
 23     /**返回信息*/
 24     private String desc = "Success.";
 25
 26     /**返回数据*/
 27     private Object data;
 28
 29     /**
 30      *
 31      * 构建函数
 32      * @author [email protected]
 33      * @created 2017年3月24日 下午4:25:23
 34      * @since
 35      */
 36     public ResObject() {
 37
 38     }
 39
 40     /**
 41      *
 42      * 描述:构造函数
 43      * @author [email protected]
 44      * @created 2017年4月18日 下午3:32:26
 45      * @since
 46      * @param data 数据
 47      */
 48     public ResObject(Object data) {
 49         super();
 50         this.data = data;
 51     }
 52
 53     /**
 54      *
 55      * 构建函数
 56      * @author [email protected]
 57      * @created 2017年3月24日 下午4:25:35
 58      * @since
 59      * @param code 返回代码
 60      * @param desc 返回信息
 61      */
 62     public ResObject(int code, String desc) {
 63         super();
 64         this.code = code;
 65         this.desc = desc;
 66     }
 67
 68     /**
 69      *
 70      * 构建函数
 71      * @author [email protected]
 72      * @created 2017年3月24日 下午4:25:39
 73      * @since
 74      * @param code 返回代码
 75      * @param desc 返回信息
 76      * @param data 返回数据
 77      */
 78     public ResObject(int code, String desc, Object data) {
 79         super();
 80         this.code = code;
 81         this.desc = desc;
 82         this.data = data;
 83     }
 84
 85     public Object getData() {
 86         return data;
 87     }
 88
 89     public void setData(Object data) {
 90         this.data = data;
 91     }
 92
 93     public int getCode() {
 94         return code;
 95     }
 96
 97     public void setCode(int code) {
 98         this.code = code;
 99     }
100
101     public String getDesc() {
102         return desc;
103     }
104
105     public void setDesc(String desc) {
106         this.desc = desc;
107     }
108
109 }

ResObject

7、异常类

 1 package com.mao.exception;
 2
 3 /**
 4  *
 5  * 项目名称:---
 6  * 模块名称:接入层
 7  * 功能描述:异常类
 8  * 创建人: [email protected]
 9  * 创建时间:2017年5月9日 下午8:22:21
10  * 修改人: [email protected]
11  * 修改时间:2017年5月9日 下午8:22:21
12  */
13 public class BusinessException extends Exception{
14
15     public BusinessException() {
16
17     }
18
19     public BusinessException(String message) {
20          super(message);
21     }
22
23 }

BusinessException

8、json工具类

  1 package com.mao.util;
  2
  3 import com.alibaba.dubbo.common.utils.StringUtils;
  4 import com.alibaba.fastjson.JSON;
  5 import com.alibaba.fastjson.TypeReference;
  6 import com.alibaba.fastjson.parser.Feature;
  7 import com.alibaba.fastjson.serializer.SerializerFeature;
  8 import com.mao.exception.BusinessException;
  9
 10 /**
 11  *
 12  * 项目名称:---
 13  * 模块名称:常用工具类
 14  * 功能描述:json工具类
 15  * 创建人: [email protected]
 16  * 创建时间:2017年3月28日 上午11:56:15
 17  * 修改人: [email protected]
 18  * 修改时间:2017年3月28日 上午11:56:15
 19  */
 20 public class JsonUtil {
 21
 22     /**
 23      *
 24      * 描述:将对象格式化成json字符串
 25      * @author [email protected]
 26      * @created 2017年4月1日 下午4:38:18
 27      * @since
 28      * @param object 对象
 29      * @return json字符串
 30      * @throws BusinessException
 31      */
 32     public static String toJson(Object object) throws BusinessException {
 33         try {
 34             return JSON.toJSONString(object, new SerializerFeature[] {
 35                 SerializerFeature.WriteMapNullValue,
 36                 SerializerFeature.DisableCircularReferenceDetect,
 37                 SerializerFeature.WriteNonStringKeyAsString });
 38         } catch (Exception e) {
 39             throw new BusinessException();
 40         }
 41     }
 42
 43     /**
 44      *
 45      * 描述:将对象格式化成json字符串(PrettyFormat格式)
 46      * @author [email protected]
 47      * @created 2017年4月1日 下午4:38:18
 48      * @since
 49      * @param object 对象
 50      * @return json字符串
 51      * @throws BusinessException
 52      */
 53     public static String toJsonFormat(Object object) throws BusinessException {
 54         try {
 55             return JSON.toJSONString(object, new SerializerFeature[] {
 56                 SerializerFeature.WriteMapNullValue,
 57                 SerializerFeature.PrettyFormat,
 58                 SerializerFeature.DisableCircularReferenceDetect,
 59                 SerializerFeature.WriteNonStringKeyAsString });
 60         } catch (Exception e) {
 61             throw new BusinessException();
 62         }
 63     }
 64
 65     /**
 66      *
 67      * 描述:转Map
 68      * @author [email protected]
 69      * @created 2017年4月1日 下午5:00:20
 70      * @since
 71      * @param obj 对象
 72      * @return object
 73      * @throws BusinessException
 74      */
 75     public static Object toJsonObject(Object obj) throws BusinessException {
 76         try {
 77             return JSON.toJSON(obj);
 78         } catch (Exception e) {
 79             throw new BusinessException();
 80         }
 81     }
 82
 83     /**
 84      *
 85      * 描述:将json串转为对象
 86      * @author [email protected]
 87      * @created 2017年4月1日 下午5:01:23
 88      * @since
 89      * @param jsonString json串
 90      * @param clazz 对象
 91      * @return
 92      * @throws BusinessException
 93      */
 94     public static <T> T fromJson(String jsonString, Class<T> clazz) throws BusinessException {
 95         try {
 96             if (StringUtils.isBlank(jsonString)) {
 97                 return null;
 98             }
 99             return (T) JSON.parseObject(jsonString, clazz);
100         } catch (Exception e) {
101             throw new BusinessException();
102         }
103     }
104
105     /**
106      *
107      * 描述:暂时不开通
108      * @author [email protected]
109      * @created 2017年4月1日 下午5:08:12
110      * @since
111      * @param jsonString
112      * @return
113      * @throws Exception
114      */
115     @SuppressWarnings("unused")
116     private static <T> T fromJson(String jsonString) throws Exception {
117         return JSON.parseObject(jsonString, new TypeReference<T>() {
118         }, new Feature[0]);
119     }
120
121 }

JsonUtil

时间: 2024-10-04 21:01:08

SpringMVC拦截器+Spring自定义注解实现权限验证的相关文章

struts2拦截器加自定义注解实现权限控制

https://blog.csdn.net/paul342/article/details/51436565 今天结合Java的Annotation和Struts2进行注解拦截器权限控制. 功能需求:添加.查找.删除三个功能,添加.查找功能需进行权限拦截判断,删除功能则不需进行权限拦截判断. 操作流程如下:客户未登录或登录已超时,提示"客户还没登陆或登陆已超时!!!",终止执行,然后跳转到某页面:否则继续往下执行. 以下模拟案例大概实现如上需求,接下来废话少说,直接copy代码 项目地

SpringMVC拦截器2(资源和权限管理)(作为补充说明)

SpringMVC拦截器(资源和权限管理) 1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet.    DispatcherServlet是前置控制器,配置在web.xml文件中的.拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller来处理.  所以我们现在web.xml中加入以下配置: [html] view plain co

SpringMVC(9)实现注解式权限验证

对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MVC中的action拦截器我们可以实现注解式的权限验证. 一.首先介绍一下action拦截器: HandlerInterceptor是Spring MVC为我们提供的拦截器接口,来让我们实现自己的处理逻辑,HandlerInterceptor 的内容如下: public interface Handl

[Java]利用拦截器和自定义注解做登录以及权限验证

1.自定义注解 需要验证登录的注解 package com.etaofinance.wap.common; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Retention

拦截器和自定义注解@interface

1 .拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在Handler执行之前或之后加入某些操作,其实就是AOP的一种实现策略. 拦截用户的请求并进行相应的处理,比如:判断用户是否登陆,判断用户权限,是否在可购买时间内,记录日志信息等.. 创建拦截器:实现HandlerInterceptor @Component public class TestInterceptor implements HandlerInterceptor { //请求在进入Handler之前,该

SpringMVC(10)实现注解式权限验证

在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异常处理. 在Spring MVC中我们可以通过以下2中途径来对异常进行集中处理: 一.继承HandlerExceptionResolver接口实现自己的处理方法,如: public class MyHandlerExceptionResolver implements HandlerExceptionRe

在MVC中添加拦截器实现登录后的权限验证

1.新建一个类 (以下实现了打印日志功能) using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcReporistory.Controllers { public class LoggerFilter : FilterAttribute, IActionFilter { void IActionFilter.On

springMVC --拦截器流程详细,使用和自定义拦截器

先看看拦截器都做些什么: 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(PageView)等. 2.权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面: 3.性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录): 4.通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Loca

SpringMVC拦截器(资源和权限管理)-login拦截

SpringMVC拦截器(资源和权限管理) 1.自定义拦截器 SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法.preHandle在业务处理器处理请求之前被调用,    postHandle在业务处理器处理请求执行完成后,生成视图之前执行,afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 .所以要想实现自己的权限管理逻辑,