还不了解后端资源拦截和权限认证?过滤器,拦截器,AOP,SpringSecurity教教你

Posted Serendipity sn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了还不了解后端资源拦截和权限认证?过滤器,拦截器,AOP,SpringSecurity教教你相关的知识,希望对你有一定的参考价值。

一.过滤器

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理
Filter:拦截请求,过滤响应
如图所示:

通过filterChain.doFilter(request,response)交给下一个过滤器链处理

主要使用场景: 统一的资源管理(如用户会话的统一管理,编码格式的统一设置等等)

使用方式: 如果不满足条件,不要执行doFilter,不往下执行(跳转页面或直接输出内容),如果满足条件,执行doFilter

二.拦截器

springMVC拦截器的实现一般有两种方式

 第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口

 第二种方式是继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter

HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的

1.preHandle(): 这个方法在业务处理器处理请求之前被调用,SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor

  1. postHandle():这个方法在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用

  2. afterCompletion():该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行

示例:
后端资源处理器:

/**
 * 后端资源处理器
 */
public class UnauthorizedInterceptor implements HandlerInterceptor 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 

        //获取Session,如果获取不到,返回null
        HttpSession session=request.getSession(false);
        if(session !=null)
            User user =(User)session.getAttribute("user");
            if(user != null)
                return true;
            
        
        //没有权限访问敏感资源,设置401状态码
        response.setStatus(401);
        return false;
    

前端资源处理器:


/**
 * 前端资源处理器
 */
public class RedirectLoginInterceptor implements HandlerInterceptor 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 
        //获取Session,如果获取不到,返回null
        HttpSession session=request.getSession(false);
        if(session !=null)
            User user =(User)session.getAttribute("user");
            if(user != null)
                return true;
            
        
        //前端敏感资源,没有登录时,直接重定向到登录页面
        response.sendRedirect("/index.html");
        return false;
    

拦截器:

 @Override
    public void addInterceptors(InterceptorRegistry registry) 
        //后端资源拦截器:没用登录的情况下,任何后端资源都无法访问,返回错误码401
        registry.addInterceptor(new UnauthorizedInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/user/login")
                .excludePathPatterns("/api/user/register");

        //前端资源拦截器:没有登录的情况下,访问任何前端页面都会重定向到index.html登录页面
        registry.addInterceptor(new RedirectLoginInterceptor())
                .addPathPatterns("/draw.html")
                .addPathPatterns("/setting.html");

    

三. AOP实现权限认证和资源拦截

面向切面拦截的是类的元数据(包、类、方法名、参数等)

相对于拦截器更加细致,而且非常灵活,拦截器只能针对URL做拦截,而AOP针对具体的代码,能够实现更加复杂的业务逻辑。

示例:根据业务操作的权限码,实现AOP拦截

1.首先,定义一个注解,定义方法需要的对应资源的权限码

import java.lang.annotation.*;
@Target(ElementType.TYPE, ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
/**
 * 定义方法需要的对应资源的权限码
 */
public @interface RequiredPermission 
    //权限码
    String code() default "";

2.切面拦截,切面会拦截指定包下的指定注解,如果没有注解定义的权限码,会拦截

@Component
@Aspect
public class PermissionProxy 

    @Resource
    private HttpSession session;

    /**
     * 切面会拦截指定包下的指定注解
     * 拦截org.example.crm.annotation的RequiredPermission注解
     *
     * @param pjp
     * @return java.lang.Object
     */
    @Around(value = "@annotation(org.example.crm.annotation.RequiredPermission)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable 
        Object result = null;
        // 得到当前登录用户拥有的权限 (session作用域)
        List<String> permissions = (List<String>) session.getAttribute("permissions");
        // 判断用户是否拥有权限
        if (null == permissions || permissions.size() < 1) 
            // 抛出认证异常
            throw new AuthException();
        

        // 得到对应的目标
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        // 得到方法上的注解
        RequiredPermission requiredPermission = methodSignature.getMethod().getDeclaredAnnotation(RequiredPermission.class);
        // 判断注解上对应的状态码
        if (!(permissions.contains(requiredPermission.code()))) 
            // 如果权限中不包含当前方法上注解指定的权限码,则抛出异常
            throw new AuthException();
        

        result = pjp.proceed();
        return result;
    



四.SpringSecurity

Spring Security:Spring家族一员。是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决
方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了 Spring IoC , DI(控制
反转Inversion of Control,DI:Dependency Injection 依赖注入) 和 AOP(面向切面编程) 功能,为应用系
统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

具体请看:添加链接描述

以上是关于还不了解后端资源拦截和权限认证?过滤器,拦截器,AOP,SpringSecurity教教你的主要内容,如果未能解决你的问题,请参考以下文章

springsecurity添加过滤器怎么针对资源拦截

拦截器的作用之session认证登录和资源拦截

036 权限控制介绍 - bos

SpringCloud系列之网关gateway-11.权限认证-分布式session替代方案

如何让spring security不拦截第三方的对接方法

玩转SpringCloud Security OAuth2资源授权动态权限扩展