文档章节

springmvc 实现注解式权限验证

岸芷汀兰
 岸芷汀兰
发布于 2015/05/22 17:34
字数 1038
阅读 573
收藏 43

对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现。但借助于Spring MVC中的action拦截器我们可以实现注解式的权限验证。

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

HandlerInterceptor是Spring MVC为我们提供的拦截器接口,来让我们实现自己的处理逻辑,HandlerInterceptor 的内容如下:

复制代码

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个方法,其含义如下:

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

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

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

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

当然借助于HandlerInterceptor我们可以实现很多其它功能,比如日志记录、请求处理时间分析等,权限验证只是其中之一。

 

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

首先添加一个账户的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上加上这个注解就可以实现权限控制功能了。

 

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


© 著作权归作者所有

岸芷汀兰
粉丝 28
博文 277
码字总数 90342
作品 0
南岸
高级程序员
私信 提问
关于以Spring3.0 MVC进行项目开发的疑问

该项目是一个行业门户,使用Java技术开发。该项目从整体角度考虑,主要有两个关注点,一个是MVC,另一个是数据持久化。原计划是使用Struts1 + Spring3 + Hibernate3来设计,但Struts1太过古老...

三阶魔方
2011/08/11
5.2K
24
shiro权限控制问题

在task控制器上加入shiro权证验证的注解没效果,用user和admin都可以使用方法,shiro权限认证注解没起作用。我在例子里加入了 AOP式方法级权限检查 的bean,还是不行。我自己又搭建了springm...

bluesky4cn
2012/09/28
2.6K
3
让Spring Security 来保护你的Spring Boot项目吧

参考资料: 书籍:Spring实战(第4版) 第9章和第14章 Spring Security 参考手册 初识 Spring Security 程序猿DD的Spring Security学习笔记 Spring Security 简介 Spring Security是一个能够为...

潇潇漓燃
2018/05/19
0
0
《Spring Boot极简教程》第16章 Spring Boot安全集成Spring Security

第16章 Spring Boot安全集成Spring Security 开发Web应用,对页面的安全控制通常是必须的。比如:对于没有访问权限的用户需要转到登录表单页面。要实现访问控制的方法多种多样,可以通过Aop...

程序员诗人
2017/04/17
0
0
Spring Security实现RBAC权限管理

Spring Security实现RBAC权限管理 一简介 在企业应用中,认证和授权是非常重要的一部分内容,业界最出名的两个框架就是大名鼎鼎的 Shiro和Spring Security。由于Spring Boot非常的流行,选择...

小忽悠
2018/06/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android面试常客之Handler全解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/fnhfire_7030/article/details/79518819 前言:又到了一年...

shzwork
11分钟前
1
0
position sticky 定位

本文转载于:专业的前端网站➫position sticky 定位 1、兼容性 https://caniuse.com/#search=sticky chrome、ios和firefox兼容性良好。 2、使用场景 sticky:粘性。粘性布局。 在屏幕范围内时...

前端老手
17分钟前
1
0
CentOS 7 yum 安装 PHP7.3 教程

参考:https://www.mf8.biz/centos-rhel-install-php7-3/ 1、首先安装 EPEL 源: yum install epel-release 安装 REMI 源: yum install http://rpms.remirepo.net/enterprise/remi-release......

dragon_tech
32分钟前
1
0
Linux物理网卡聚合及桥接

Linux内部实现的bridge可以把一台机器上的多张网卡桥接起来,从而把自己作为一台交换机。同时,LInux bridge还支持虚拟端口,即桥接的不一定都是物理网卡接口,还可以是虚拟接口。目前主要表...

xiangyunyan
33分钟前
1
0
一起来学Java8(一)——函数式编程

在这篇文章中,我们将了解到在Java8下如何进行函数式编程。 函数式编程 所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。 首先来看下JavaScript如何进行函...

猿敲月下码
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部