在上一篇 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 使用拦截器优雅地实现权限验证功能的更多相关文章

  1. spring mvc +cookie+拦截器功能 实现系统自动登陆

    先看看我遇到的问题: @ResponseBody @RequestMapping("/logout") public Json logout(HttpSession session ...

  2. Spring mvc登录拦截器

    自己实现的第一个Spring mvc登录拦截器 题目要求:拒绝未登录用户进入系统,只要发现用户未登录,则将用户请求转发到/login.do要求用户登录 实现步骤: 1.在spring的配置文件中添加登 ...

  3. 玩转spring MVC(七)----拦截器

    继续在前边的基础上来学习spring MVC中拦截器的使用,下面通过一个例子来实现(完整项目在这里下载:http://download.csdn.net/detail/u012116457/84334 ...

  4. springboot + 拦截器 + 注解 实现自定义权限验证

    springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ...

  5. spring boot 使用拦截器,注解 实现 权限过滤

    http://www.cnblogs.com/zhangXingSheng/p/7744997.html spring boot 使用拦截器 实现 用户登录拦截 http://www.cnblogs. ...

  6. struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo

    理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...

  7. [转载] Spring MVC - 处理器拦截器

    5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器)类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理.   ...

  8. [Spring MVC] - Interceptor 拦截器

    Spring MVC中的Interceptor与Struts2的差不多. 下面是一个简单的Interceptor登陆验证例子: 1.需要在spring的配置文件中加入这段: <!-- 自定义拦截 ...

  9. spring mvc 配置文件拦截器过滤url

    最近在用spring mvc拦截器,sprin 版本号4.0.6.RELEASE, <mvc:interceptor> <mvc:mapping path="/admin/ ...

随机推荐

  1. 二模 (12)day2

    第一题: 题目大意: 有N颗糖,两个人轮流取,每次只能取质数颗,不能取的输.求先取者若必胜,最少需要多少步胜利.(N<=10000) 解题过程: 1.看到N的范围比较小,先打个素数表,然后dp即 ...

  2. 快餐问题(dp好题)

    Peter最近在R市开了一家快餐店,为了招揽顾客,该快餐店准备推出一种套餐,该套餐由A个 汉堡,B个薯条和C个饮料组成.价格便宜.为了提高产量,Peter从著名的麦当劳公司引进了N条 生产线.所有的生 ...

  3. load image

    <img data-src="/path/to/image.jpg" alt="">img { opacity: 1; transition: op ...

  4. wp8.1 Study1: 页面导航&页面间值传递

    摘要:wp8.1与wp8中很多API是不一样了,wp8.1把以前wp7.x时的api去掉了,更多与win8.1的API相似.比如以下的页面导航和页面之间的值传递 1.页面导航 利用Frame.Navi ...

  5. SQL CAST, CONVERT 比较

    本文转自:http://www.cnblogs.com/denylau/archive/2010/12/01/1893371.html if (@StartTime > @EndTime)    ...

  6. “System.Threading.ThreadAbortException”类型的第一次机会异常在 mscorlib.dll 中发

    问题原因: Thread.Abort 方法 .NET Framework 4  其他版本   1(共 1)对本文的评价是有帮助 - 评价此主题 在调用此方法的线程上引发 ThreadAbortExce ...

  7. Quartz之主方法运行

    import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger; impo ...

  8. xlistview的java(头)

    package com.bwie.xlistviews; import com.bwie.test.R; import android.content.Context;import android.u ...

  9. 自然数n的分解

    输入自然数n(n<100),输出所有和的形式.不能重复. 如:4=1+1+2:4=1+2+1;4=2+1+1 属于一种分解形式. 样例: 输入: 7 输出: 7=1+6 7=1+1+5 7=1+ ...

  10. Asp.Net中Ajax实现登陆判断

    Default.aspx: <head runat="server"> <title>无标题页</title> <script type= ...