zoukankan      html  css  js  c++  java
  • 基于SpringMVC拦截器和注解实现controller中访问权限控制

    SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。

    1. preHandle在业务处理器处理请求之前被调用;
    2. postHandle在业务处理器处理请求执行完成后,生成视图之前执行;
    3. afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等;

    所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。

    一、自定义拦截器配置方法

    1. 在sping的xml配置中可以用<mvc:interceptors>和<mvc:interceptor>来配置拦截器类(实现HandlerInterceptorAdapter)
    2. 在javaConfig中配置通过WebMvcConfiguration的实现类配置拦截器类(实现HandlerInterceptorAdapter)

    二、示例

    2.1、javaconfig中配置SpringMVC示例

    1、新建一个springboot项目auth-demo2

    2、权限校验相关的注解

    复制代码
    package com.dxz.authdemo2.web.auth;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Permission {
        /** 检查项枚举 */
        PermissionEnum[] permissionTypes() default {};
    
        /** 检查项关系 */
        RelationEnum relation() default RelationEnum.OR;
    }
    
    package com.dxz.authdemo2.web.auth;
    
    import java.io.PrintWriter;
    import java.lang.annotation.Annotation;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    
    /**
     * 权限检查拦截器 
     */
    @Component
    public class PermissionCheckInterceptor extends HandlerInterceptorAdapter {  
        /** 权限检查服务 */
        @Autowired
        private PermissionCheckProcessor permissionCheckProcessor;  
        @Override  
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
            //Class<?> clazz = handler.getClass();  
            Class<?> clazz = ((HandlerMethod)handler).getBeanType();
            System.out.println("PermissionCheckInterceptor.preHandle()" + clazz);
            for(Annotation a : clazz.getAnnotations()){
                System.out.println(a);
            }
            if (clazz.isAnnotationPresent(Permission.class)) { 
                Permission permission = (Permission) clazz.getAnnotation(Permission.class);  
                return permissionCheckProcessor.process(permission, request, response);  
            }  
            return true;  
        }  
        
        public boolean preHandle2(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
            System.out.println("SecurityInterceptor:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod());
            HttpSession session = request.getSession();
            if (session.getAttribute("uid") == null) {
                System.out.println("AuthorizationException:未登录!"+request.getMethod());
                if("POST".equalsIgnoreCase(request.getMethod())){
                    response.setContentType("text/html; charset=utf-8");  
                    PrintWriter out = response.getWriter();   
                    out.write("未登录!");
                    out.flush();
                    out.close();
                }else{
                    response.sendRedirect(request.getContextPath()+"/login"); 
                }
                return false;
            } else {
                return true;
            } 
        }  
    }  
    
    package com.dxz.authdemo2.web.auth;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Component;
    @Component
    public class PermissionCheckProcessor {
        public boolean process(Permission permission, HttpServletRequest request, HttpServletResponse response) {
            PermissionEnum[] permissionTypes = permission.permissionTypes();
            try {
                String uid = request.getParameter("uid");
                if ("duanxz".equals(uid)) {
                    System.out.println("认证成功");
                    return true;
                } else {
                    System.out.println("认证失败");
                    return false;    
                }
            } catch (Exception e) {
                return false;
            }
        }
    }
    
    package com.dxz.authdemo2.web.auth;
    
    public enum PermissionEnum {
        DEVELOPER_VALID, DEVELOPER_FREEZE;
    }
    
    package com.dxz.authdemo2.web.auth;
    
    public enum RelationEnum {
        OR, AND;
    }
    复制代码

    3、SpringMVC拦截器配置

    复制代码
    package com.dxz.authdemo2.web.auth;
    
    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;
    
    @Configuration
    public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
    
        @Autowired
        PermissionCheckInterceptor permissionCheckInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // addPathPatterns 用于添加拦截规则
            // excludePathPatterns 用户排除拦截
            // 映射为 user 的控制器下的所有映射
            registry.addInterceptor(permissionCheckInterceptor).addPathPatterns("/admin/*").excludePathPatterns("/index", "/");
            super.addInterceptors(registry);
        }
    }
    复制代码

    4、测试controller

    复制代码
    package com.dxz.authdemo2.web;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    
    import com.dxz.authdemo2.web.auth.Permission;
    import com.dxz.authdemo2.web.auth.PermissionEnum;
    
    @Controller  
    @RequestMapping("/admin")  
    @Permission(permissionTypes = { PermissionEnum.DEVELOPER_VALID })  
    public class AppDetailController {  
        @RequestMapping(value="/appDetail", method = RequestMethod.GET)  
        public String doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {  
            //1. 业务操作,此处省略  
            System.out.println("appDetail.htm 处理中...");
            return "appDetail";
        }
    }  
      
    package com.dxz.authdemo2.web;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import com.dxz.authdemo2.web.auth.Permission;
    import com.dxz.authdemo2.web.auth.PermissionEnum;
    
    @Controller  
    @RequestMapping("index")  
    public class IndexController {  
        @RequestMapping(method = RequestMethod.GET)  
        public void doGet(ModelMap modelMap, HttpServletRequest httpServletRequest) {  
            System.out.println("index");
        }  
    }  
    复制代码

    cotroller中的jsp文件appDetail.jsp

    <html>
    <h1>appDetail</h1>
    </html>

    启动类:

    复制代码
    package com.dxz.authdemo2;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.servlet.ViewResolver;
    import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    @EnableWebMvc
    @EnableAutoConfiguration
    @SpringBootApplication
    public class AuthDemo2Application {
    
        public static void main(String[] args) {
            SpringApplication.run(AuthDemo2Application.class, args);
        }
    
        // 配置JSP视图解析器
        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/views/");
            resolver.setSuffix(".jsp");
            return resolver;
        }
    }
    复制代码

    结果:

    访问:http://localhost:8080/admin/appDetail?uid=duanxz2

    访问:http://localhost:8080/admin/appDetail?uid=duanxz

    2.2、xml中配置SpringMVC示例

    首先在springmvc.xml中加入自己定义的拦截器我的实现逻辑PermissionCheckInterceptor,如下:

    复制代码
    <!--配置拦截器, 多个拦截器,顺序执行 -->  
    <mvc:interceptors>    
        <mvc:interceptor>    
            <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->  
            <mvc:mapping path="/" />  
            <mvc:mapping path="/user/**" />  
            <mvc:mapping path="/test/**" />  
            <bean class="com.dxz.authdemo2.web.auth.PermissionCheckInterceptor"></bean>    
        </mvc:interceptor>  
        <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->  
    </mvc:interceptors> 
    复制代码

      

     
     
  • 相关阅读:
    phpmyadmin和网页上面的乱码问题
    整理: Android HAL
    warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]-给char* 形参 传入 宏定义字符串
    ubuntu 输入法莫名其妙变繁体
    linux内核版本号添加字符/为何有时会自动添加“+”号以及怎么去掉
    Unable to handle kernel NULL pointer dereference at virtual address 00000000
    Ubuntu 18.04 安装 Samba 服务器及配置
    linux查看版本信息
    图解:电压掉电监测电路如何实现检测工作?
    精密全波整流+一阶RC滤波器检测市电电压
  • 原文地址:https://www.cnblogs.com/exmyth/p/10742392.html
Copyright © 2011-2022 走看看