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/ ...
随机推荐
- 存储过程Oracle学习(一)
一.简介 存储过程:就是在数据库中创建的一段程序,供别人调用 .其实我感觉跟定义一个方法相似 二.无参存储过程 如下,经典的输出"Hello World"来入门存储过程 创建一个存 ...
- Zooming MKMapView to fit annotation pins
http://stackoverflow.com/questions/4680649/zooming-mkmapview-to-fit-annotation-pins - (MKCoordinateR ...
- 【HDU2087】KMP
KMP算法其实很好理解,就是在匹配串中找最近的相同的串. 下面是HDU的2087: #include<iostream> #include<cstdio> #include&l ...
- Cisco IOS debug command reference Command A through D
debug aaa accounting through debug auto-config debug aaa accounting : to display information on acco ...
- git 克隆项目 与 分支简单操作
git clone http://abcde.com/myproject/abc.git 克隆远程项目到本地githome文件夹git branch -a 查看所有分支 包括远程和本地 *号开头表示当 ...
- 用C#感受MongoDB MapReduce之魅力 转
MapReduce这个名词随着hadoop的用户的增多,越来越被人关注.MapReduce可谓MongoDB之中的亮点,我也想深入了解MapReduce,加上MongoDB操作简单,所以就选择了它.M ...
- php注册审核显示
用户进行注册,管理员通过审核后,使用户通过审核 数据库建表 create database mydb; use mydb; create table User ( Uid int auto_incre ...
- ASP.NET中把xml转为dataset与xml字符串转为dataset及dataset转为xml的代码
转自:http://www.cnblogs.com/_zjl/archive/2011/04/08/2009087.html XmlDatasetConvert.csusing System;usin ...
- C语言数据类型在IA32中的大小
这个主要是一些常识问题,以及在使用AT&T语法汇编时会使用的编码后缀: C声明 Intel数据类型 汇编后缀 大小(byte) char 字节 b 1 short 字 w 2 int ...
- Ubuntu系统启用Apache Mod_rewrite模块
在终端中执行 sudo a2enmod rewrite 指令后,即启用了 Mod_rewrite 模块. 另外,也可以通过将 /etc/apache2/mods-available/rewrite.l ...