SpringMVC学习系列(9) 之 实现注解式权限验证

对大部分系统来讲都须要权限管理来决定不一样用户能够看到哪些内容,那么如何在Spring MVC中实现权限验证呢?固然咱们能够继续使用servlet中的过滤器Filter来实现。但借助于Spring MVC中的action拦截器咱们能够实现注解式的权限验证。html

一.首先介绍一下action拦截器:java

HandlerInterceptor是Spring MVC为咱们提供的拦截器接口,来让咱们实现本身的处理逻辑,HandlerInterceptor 的内容以下:web

public interface HandlerInterceptor {  
    boolean preHandle(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler)   
            throws Exception;  
  
    void postHandle(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler, ModelAndView modelAndView)   
            throws Exception;  
  
    void afterCompletion(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler, Exception ex)  
            throws Exception;  
}

能够看到接口有3个方法,其含义以下:spring

preHandle:在执行action里面的处理逻辑以前执行,它返回的是boolean,这里若是咱们返回true在接着执行postHandle和afterCompletion,若是咱们返回false则中断执行。mvc

postHandle:在执行action里面的逻辑后返回视图以前执行。app

afterCompletion:在action返回视图后执行。eclipse

HandlerInterceptorAdapter适配器是Spring MVC为了方便咱们使用HandlerInterceptor而对HandlerInterceptor 的默认实现,里面的3个方法没有作任何处理,在preHandle方法直接返回true,这样咱们继承HandlerInterceptorAdapter后只须要实现3个方法中咱们须要的方法便可,而不像继承HandlerInterceptor同样无论是否须要3个方法都要实现。jsp

固然借助于HandlerInterceptor咱们能够实现不少其它功能,好比日志记录、请求处理时间分析等,权限验证只是其中之一。ide

 

二.下面咱们就来一步一步来完成注解式权限验证的功能。post

首先添加一个帐户的Controller和登陆的Action及视图来模拟在没有权限时跳转到登录页面,内容分别以下:

com.demo.web.controllers包中的AccountController.java:

package com.demo.web.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(value = "/account")
public class AccountController {
    
    @RequestMapping(value="/login", method = {RequestMethod.GET})
    public String login(){
        
        return "login";
    }
    
}

views文件夹下的视图login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    这里是登陆界面
</body>
</html>

新建包com.demo.web.auth,添加自定义注解AuthPassport,内容以下:

package com.demo.web.auth;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthPassport {
    boolean validate() default true;
}

添加本身的拦截器实现AuthInterceptor继承于HandlerInterceptorAdapter,内容以下:

package com.demo.web.auth;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class AuthInterceptor extends HandlerInterceptorAdapter {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        if(handler.getClass().isAssignableFrom(HandlerMethod.class)){
            AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class);
            
            //没有声明须要权限,或者声明不验证权限
                if(authPassport == null || authPassport.validate() == false)
                return true;
            else{                
                //在这里实现本身的权限验证逻辑
                if(false)//若是验证成功返回true(这里直接写false来模拟验证失败的处理)
                    return true;
                else//若是验证失败
                {
                    //返回到登陆界面
                    response.sendRedirect("account/login");
                    return false;
                }       
            }
        }
        else
            return true;   
     }
}

配置项目的springservlet-config.xml添加以下内容:

<mvc:interceptors>  
    <!-- 国际化操做拦截器 若是采用基于(请求/Session/Cookie)则必需配置 --> 
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />  
    <!-- 若是不定义 mvc:mapping path 将拦截全部的URL请求 -->
    <bean class="com.demo.web.auth.AuthInterceptor"></bean>
</mvc:interceptors>

这样在执行每一个action方法是都会调用AuthInterceptor处理,当判断action上有咱们定义AuthPassport注解时就会执行里面的权限验证逻辑。

运行项目:

1

能够看到执行了咱们在springservlet-config.xml定义的HelloworldController的index方法。

<!-- 若是当前请求为“/”时,则转发到“/helloworld/index" -->
<mvc:view-controller path="/" view-name="forward:/helloworld/index"/>

下面咱们在HelloworldController的index方法上加上自定义注解AuthPassport:

@AuthPassport
@RequestMapping(value={"/index","/hello"})
public ModelAndView index(){
    
    ModelAndView modelAndView = new ModelAndView();  
    modelAndView.addObject("message", "Hello World!");  
    modelAndView.setViewName("index");  
    return modelAndView;
}

从新运行项目:

2

能够看到正确执行了权限判断逻辑,这样咱们只须要在咱们在须要权限验证的action上加上这个注解就能够实现权限控制功能了。

 

注解式权限验证的内容到此结束。

 

代码下载:http://pan.baidu.com/s/1ntFOB3N

注: 以前没注意前11篇的示例代码,不知道为何当时打包上传上去的是没有.project项目文件的,致使下载后不能直接导入eclipse运行,虚拟机又 被我删掉了,这些示例代码也没有备份,可是代码文件还在的,因此能够新建一个Dynamic Web Project把对应的配置文件和controller还有view导入就能够了,给你们形成的不便说声抱歉。

相关文章
相关标签/搜索