Spring MVC 使用拦截器优雅地实现权限验证功能
在上一篇 SpringAOP 实现功能权限校验功能 中虽然用AOP通过抛异常,请求转发等勉强地实现了权限验证功能,但感觉不是那么完美,应该用拦截器来实现才是最佳的,因为拦截器就是用来拦截请求的,在请求层面进行权限验证是最好的时机。
假设下面的请求需要进行权限验证,在请求中通过参数params指定必须带有Helper.PARAM_FUNCTION_ID参数,这样拦截器通过判断是否带有该参数,如果带有则进行权限验证,否则不作处理。
@RequestMapping(value = "/moduleAccess.do",params=Helper.PARAM_FUNCTION_ID, method = RequestMethod.POST, produces="text/html;charset=utf-8")
@ResponseBody
public String moduleAccess(String action,FrmModule module) {
int rs = -1;
try{
if(Helper.F_ACTION_CREATE.equals(action)){
rs = moduleService.access(module,Helper.DB_ACTION_INSERT);
//module.setModuleid(rs);
module = moduleService.selectByPrimaryKey(rs);
}else if(Helper.F_ACTION_EDIT.equals(action)){
rs = moduleService.access(module,Helper.DB_ACTION_UPDATE);
module = moduleService.selectByPrimaryKey(module.getModuleid());
}else if(Helper.F_ACTION_REMOVE.equals(action)){
rs = moduleService.access(module,Helper.DB_ACTION_DELETE);
}else{
return JSON.toJSONString(new Result(false,"请求参数错误:action"));
}
}catch(Exception e){
e.printStackTrace();
return JSON.toJSONString(new Result(false,"操作失败,出现异常,请联系管理员!"));
}
if(rs<0){
return JSON.toJSONString(new Result(false,"操作失败,请联系管理员!"));
}
return JSON.toJSONString(new Result(true,module));
}
那么对应的拦截器就直接用登录验证的那个拦截器即可,SecurityInterceptor
package com.jykj.demo.filter;
import java.io.PrintWriter;
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.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.jykj.demo.entity.SysUser;
import com.jykj.demo.service.SysUserRolePermService;
import com.jykj.demo.util.Helper;
import com.jykj.demo.util.Result;
/**
* 1.此拦截器用于拦截所有请求,用于登录权限验证
* 2.拦截 带 moduleId 参数的请求,在渲染视图之前返回 模块权限值
* @author Administrator
*
*/
public class SecurityInterceptor implements HandlerInterceptor{
@Autowired
SysUserRolePermService sysUserRolePermService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("SecurityInterceptor preHandle:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod());
HttpSession session = request.getSession();
if (session.getAttribute(Helper.SESSION_USER) == 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(JSON.toJSONString(new Result(false,"未登录!")));
out.flush();
out.close();
}else{
response.sendRedirect(request.getContextPath()+"/login");
}
return false;
} else {
Object obj = request.getParameter(Helper.PARAM_FUNCTION_ID);
if(obj==null) return true;//没有带功能参数不需要验证
int functionId = Integer.parseInt(obj.toString());
String rs = sysUserRolePermService.permissionValidate(functionId);
System.out.println("校验结果:"+rs);
if(rs.trim().isEmpty()){
return true;//正常通过
}else{
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.write(JSON.toJSONString(new Result(false,rs)));
out.flush();
out.close();
return false;
}
}
}
//模块权限值
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
/*
Object obj = request.getParameter(Helper.PARAM_MODULE_ID);
System.out.println(Helper.PARAM_MODULE_ID+":"+obj);
if(obj == null) return;//如果没有moduleId 参数,否则什么都不做,否则返回模块权限值
System.out.println("SecurityInterceptor postHandle:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod());
SysUser loginUser = (SysUser)request.getSession().getAttribute(Helper.SESSION_USER);
int value = sysUserRolePermService.getModulePerm(loginUser.getUserid(),Integer.parseInt(obj.toString()));
modelAndView.addObject(Helper.MVALUE,value);
*/
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
拦截器配置不变
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/> <!-- 拦截/ /test /login 等等单层结构的请求 -->
<mvc:mapping path="/**/*.aspx"/><!-- 拦截后缀为.aspx的请求 -->
<mvc:mapping path="/**/*.do"/><!-- 拦截后缀为 .do的请求 -->
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/signIn"/>
<mvc:exclude-mapping path="/register"/>
<bean class="com.jykj.demo.filter.SecurityInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
这样即实现了对某个功能的权限校验的功能
客户端发送 /moduleAccess.do 请求,该请求带有参数Helper.PARAM_FUNCTION_ID,其值为某个功能的id
然后拦截器拦截该请求,判断出带有该参数,则对其进行权限校验,如果未通过,写response给客户端,格式是json的字符串,并返回false表示请求已由本拦截器处理了,不会往下执行(返回true表示正常往下执行)。这样就达到了权限验证的目的。这是相对更优雅的实现方式,最起码比上一篇讲的用AOP来实现更优雅。
另外拦截器的postHandle方法是在控制器执行结束,页面渲染之前执行的,所以可以用来给页面添加或修改model属性。
Spring MVC 使用拦截器优雅地实现权限验证功能的更多相关文章
- spring mvc +cookie+拦截器功能 实现系统自动登陆
先看看我遇到的问题: @ResponseBody @RequestMapping("/logout") public Json logout(HttpSession session ...
- Spring mvc登录拦截器
自己实现的第一个Spring mvc登录拦截器 题目要求:拒绝未登录用户进入系统,只要发现用户未登录,则将用户请求转发到/login.do要求用户登录 实现步骤: 1.在spring的配置文件中添加登 ...
- 玩转spring MVC(七)----拦截器
继续在前边的基础上来学习spring MVC中拦截器的使用,下面通过一个例子来实现(完整项目在这里下载:http://download.csdn.net/detail/u012116457/84334 ...
- springboot + 拦截器 + 注解 实现自定义权限验证
springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ...
- spring boot 使用拦截器,注解 实现 权限过滤
http://www.cnblogs.com/zhangXingSheng/p/7744997.html spring boot 使用拦截器 实现 用户登录拦截 http://www.cnblogs. ...
- struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo
理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...
- [转载] Spring MVC - 处理器拦截器
5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器)类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. ...
- [Spring MVC] - Interceptor 拦截器
Spring MVC中的Interceptor与Struts2的差不多. 下面是一个简单的Interceptor登陆验证例子: 1.需要在spring的配置文件中加入这段: <!-- 自定义拦截 ...
- spring mvc 配置文件拦截器过滤url
最近在用spring mvc拦截器,sprin 版本号4.0.6.RELEASE, <mvc:interceptor> <mvc:mapping path="/admin/ ...
随机推荐
- linux下挂载硬盘,解决阿里云挂载后重启消失的问题
完整的阿里云挂载数据盘方法如下: 1.入手阿里云后查看有几块硬盘:(只显示概况,不显示分区情况) fdisk -l|grep Disk 2.查看硬盘分区 fdisk -l 如果有提示:disk /de ...
- fetch VS AJAX
fetch('https://mywebsite.com/endpoint/', { method: 'POST', headers: { 'Accept': 'application/json', ...
- [开发笔记]-Visual Studio 2012中为创建的类添加注释的模板
为类文件添加注释,可以让我们在写代码时能够方便的查看这个类文件是为了实现哪些功能而写的. 一:修改类文件模板 找到类模版的位置:C:\Program Files (x86)\Microsoft Vis ...
- Google https服务被屏蔽
根据Google透明度报告显示,从上周(5月27日)开始,Google的部分服务开始被屏蔽,其中最主要的是HTTPS搜索服务和Google登录服务,所有版本的Google都受到影响,包括Google. ...
- 如何区别PeekMessage&GetMessage SendMessage&PostMessage
转自http://blog.csdn.net/young0325/article/details/6430664 Peekmessage和Getmessage都是向系统的消息队列中取得消息,不过性质不 ...
- 2016 - 1 -19 初学HTML5 第一天
1.HTML COMMANDS MHTL commands called elements.Usually, an element has a start tag and an end tag e.g ...
- UNIX 网络编程第三版
第五章p102: ps -t pts/6 -o pid,ppid,tty,stat,args,wchan 在我的系统上运行时出现:TTY not found linux发行版为mint17.1 改用 ...
- 开启Ubuntu php错误提示 ZT
开启Ubuntu php错误提示 在Ubuntu下,LAMP中PHP错误是不提示的,只会出现一个空白页.当然,这对于运行的生产环境来说是必须的.但有时候也需要查看生产环境上错误提示,那么只要通用下面简 ...
- HTML中的鼠标光标属性
在网页中默认的鼠标指针只有两种,一种是最普通的箭头,另一种是当移动到链接上时出现的“小手”.但现在越来越多的网页都使用了CSS鼠标指针技术,当将鼠标移动到链接上时,可以看到多种不同的效果.CSS可以通 ...
- Mac OS 使用Git
入门教程的流程: 什么是Git----------------->为什么选择Git----------------->如何安装Git到MAC OS X------------------& ...