Spring AOP实现功能权限校验功能的示例代码

论坛 期权论坛 脚本     
niminba   2021-5-23 02:57   1814   0

实现功能权限校验的功能有多种方法,其一使用拦截器拦截请求,其二是使用AOP抛异常。

首先用拦截器实现未登录时跳转到登录界面的功能。注意这里没有使用AOP切入,而是用拦截器拦截,因为AOP一般切入的是service层方法,而拦截器是拦截控制器层的请求,它本身也是一个处理器,可以直接中断请求的传递并返回视图,而AOP则不可以。

1.使用拦截器实现未登录时跳转到登录界面的功能

1.1 拦截器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.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.jykj.demo.util.Helper;
import com.jykj.demo.util.Result;

public class SecurityInterceptor implements HandlerInterceptor{
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
   throws Exception {
  System.out.println("SecurityInterceptor:"+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 {
   return true;
  }
 }

 @Override
 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
   ModelAndView modelAndView) throws Exception {
  // TODO Auto-generated method stub
 }

 @Override
 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
   throws Exception {
  // TODO Auto-generated method stub
 }
}

1.2.spring-mvc.xml(拦截器配置部分)

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
 <mvc:resources mapping="/resources/**" location="/resources/" />
<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>

这里需要特别说明:拦截器拦截的路径最好是带有后缀名的,否则一些静态的资源文件不好控制,也就是说请求最好有一个统一的格式如 .do 等等,这样匹配与过滤速度会非常快。如果不这样,例如 用 /** 来拦截所有的请求,则页面渲染速度会非常慢,因为资源文件也被拦截了。

2.使用AOP实现功能权限校验

对于功能权限校验也可以类似地用拦截器来实现,只不过会拦截所有的请求,对不需要权限校验的请求没有很好的过滤功能,所以采用AOP指定拦截需要校验的方法的方式来实现之。

2.1 切面类 PermissionAspect

package com.jykj.demo.filter;
import java.io.IOException;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import com.jykj.demo.annotation.ValidatePermission;
import com.jykj.demo.exception.AccessDeniedException;
import com.jykj.demo.service.SysUserRolePermService;
/**
 * 事件日志 切面,凡是带有 @ValidatePermission 以及@ResponseBody注解 控制器 都要进行 功能权限检查,
 * 若无权限,则抛出AccessDeniedException 异常,该异常将请求转发至一个控制器,然后将异常结果返回
 * @author Administrator
 *
 */
public class PermissionAspect {
 @Autowired
 SysUserRolePermService sysUserRolePermService;
 public void doBefore(JoinPoint jp) throws IOException{
  System.out.println(
    "log PermissionAspect Before method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName());
  Method soruceMethod = getSourceMethod(jp);
  if(soruceMethod!=null){
   ValidatePermission oper = soruceMethod.getAnnotation(ValidatePermission.class);
   if (oper != null) {
    int fIdx = oper.idx();
    Object[] args = jp.getArgs();
    if (fIdx>= 0 &&fIdx<args.length){
     int functimX]J[\SNY[[
H]]]^][^[
NB[\H
[BY[\\Y

HOHJH]\^]\X\\\Z\[[Y]J[\\Y

K[[Y
NX^[^
^^[XX
N]\l9kng9a9o n.;CBCBOB]B+#:/+)"P[Y]T\Z\[d\y\c!ycmkd9c!y`9"yyc9b!#:/-+'*9n:++)"P[Y]T\Z\[yc9b!#9g*9b!n&/)9z+y+"P\yiy#y. 9- n.;")"P\y&y"/9o n.:/皜ke,Bd)b&{n:+ 9.*!.byo n.9d#l!+`ad$yb,9. 9.*d"9:)\B`&/- H[PX\+`+`k9y#9m[Y]T\Z\[d\{nm.%9"yb9clY:/-c!y#9iЙYz`&`&/lY;k"9-:/c9`(zj;"(zj:`&/z/#9ni#9d)b&y.byo n.X\[YY^[+ n.9ez# :)zacyo n.9i!9fj;nmc`\[YY;d#k9j\[YY9i!9+`/ 9.*c!yd*9i,z-)y/kk- /- H[PX\+`i9(zj9i,z-){/k9c,9.\[YY:+`d)b&yhi ./b9. 9.*i)d9cykkBB."l,y+j:`yk{n#9&)9ki.h9"y`9n+b{.g&i&i&+/c.
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP