SpringMVC(9)实现注解式权限验证
对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在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注解时就会执行里面的权限验证逻辑。
运行项目:

可以看到执行了我们在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;
}
重新运行项目:

可以看到正确执行了权限判断逻辑,这样我们只需要在我们在需要权限验证的action上加上这个注解就可以实现权限控制功能了。
SpringMVC(9)实现注解式权限验证的更多相关文章
- SpringMVC实现注解式权限验证
SpringMVC学习系列(9) 之 实现注解式权限验证 对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servle ...
- SpringMVC实现注解式权限验证(转)
SpringMVC学习系列(9) 之 实现注解式权限验证 对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用serv ...
- SpringMVC学习系列(9) 之 实现注解式权限验证
对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...
- SpringMVC学习(9):实现注解式权限验证
对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...
- SpringMVC(10)实现注解式权限验证
在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异 ...
- SpringMVC使用@Valid注解进行数据验证
SpringMVC使用@Valid注解进行数据验证 from:https://blog.csdn.net/zknxx/article/details/52426771 我们在做Form表单提交的时 ...
- springMVC中实现用户登录权限验证
通过上网搜资料显示,使用filter和interceptor都可以实现.不过推荐使用interceptor. 下面就使用Interceptor实现用户登录权限验证功能. 拦截器需要实现Inceptor ...
- SSM-SpringMVC-14:SpringMVC中大话注解式开发基础--呕心沥血版
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 注解的基础我不再多啰嗦,百度一搜很多,很详细啊,我就讲一下SpringMVC中的注解入门 通过注解的方式定义 ...
- SpringMVC拦截器+Spring自定义注解实现权限验证
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
随机推荐
- nginx 的基础知识(一)
Nginx HTTP 和 反向代理web服务器 epoll 占用少的系统资源.支持更多的并发连接 负载均衡 安装简单.配置灵活 热部署.启动快.不间断服务情况下对软件配置进行升级 反向代理 反向代理 ...
- springboot 非端口模式启动
@SpringBootApplication @ComponentScan(basePackages = {"demo.test"}) public class ReportApp ...
- Jmeter——元件扩展,使其功能更全面
工具扩展 在之前的博文中,有介绍自定义函数.Java请求扩展,博文如下: Jmeter二次开发--基于Java请求 Jmeter二次开发--自定义函数 上述内容,是按自己的需要来进行针对性扩展,从而实 ...
- MindSpore 高阶优化器
MindSpore 高阶优化器 MindSpore自研优化器THOR(Trace-based Hardware-driven layer-ORiented Natural Gradient Desce ...
- 3D目标检测(CVPR2020:Lidar)
3D目标检测(CVPR2020:Lidar) LiDAR-Based Online 3D Video Object Detection With Graph-Based Message Passing ...
- BlazorCharts 原生图表库的建设历程
作者:陈超超 Ant Design Blazor 项目贡献者,拥有十多年从业经验,长期基于.Net技术栈进行架构与开发产品的工作,现就职于正泰集团. 邮箱:timchen@live.com 欢迎各位读 ...
- 重新整理 mysql 基础篇————— mysql 事务[三]
前言 简单整理一下事务. 正文 事务有四大特性: 1.原子性(atomicity) 一个事务必须被视为一个不可分割的最小单元. 2.一致性(consistency) 数据库总是从一个一致性的状态转换到 ...
- 【NX二次开发】拉伸面、拉伸封闭曲线成片体UF_MODL_create_extrusion
用那几个拉伸,不能将封闭的曲线拉伸成片体,用UF_MODL_create_extrusion函数是可以的,下面是例子. 帮助上说拉伸片体不能有拔模角度,应该是错误的,下面是一个封闭曲线带拔模角度拉伸片 ...
- 【模板】Tarjian求LCA
概念 公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点 举个例子吧,如下图所示4和5的最近公共祖先是2,5和3的最近公共祖先是1,2和1的最近公共祖先是1. 算法 常用的求LCA的算法有:Ta ...
- NOIP模拟测试「简单的区间·简单的玄学·简单的填数·简单的序列」
简单的区间 $update$ 终于$AC$了 找到$(sum[r]+sum[l](sum表示以中间点为基准的sum)-mx)\%k==0$的点 注意这里$sum$表示是以$mid$为基准点,(即$su ...