You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security:如何在Filter中获取接口的权限配置

在Spring Boot过滤器中获取@PreAuthorize指定的权限

核心思路:通过Spring的RequestMappingHandlerMapping匹配当前请求对应的控制器方法,再从方法上提取@PreAuthorize注解的权限表达式并解析。

具体实现步骤

  1. 注入RequestMappingHandlerMapping
    在自定义过滤器中注入该Bean,用于根据请求定位到对应的控制器处理方法。

  2. 获取当前请求的HandlerMethod
    在doFilterInternal方法中,通过RequestMappingHandlerMapping获取请求对应的HandlerExecutionChain,进而得到HandlerMethod实例。

  3. 解析@PreAuthorize注解中的权限
    从HandlerMethod上提取@PreAuthorize注解,解析其中的SpEL表达式,提取出目标权限值。

完整代码示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AuthTokenFilter extends OncePerRequestFilter {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws IOException, ServletException {
        try {
            // 获取当前请求对应的控制器方法链
            HandlerExecutionChain handlerChain = requestMappingHandlerMapping.getHandler(req);
            if (handlerChain != null && handlerChain.getHandler() instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handlerChain.getHandler();
                
                // 提取方法上的@PreAuthorize注解
                PreAuthorize preAuthorize = handlerMethod.getMethodAnnotation(PreAuthorize.class);
                if (preAuthorize != null) {
                    String expression = preAuthorize.value();
                    // 解析hasAuthority('XXX')格式的权限表达式
                    Pattern pattern = Pattern.compile("hasAuthority\\('([^']+)'\\)");
                    Matcher matcher = pattern.matcher(expression);
                    if (matcher.find()) {
                        String requiredAuthority = matcher.group(1);
                        // 此处可根据业务需求使用获取到的权限值
                        System.out.println("当前接口所需权限:" + requiredAuthority);
                    }
                }
            }
        } catch (Exception e) {
            // 处理请求未匹配到控制器方法等异常情况
            e.printStackTrace();
        }
        
        // 继续执行过滤器链
        filterChain.doFilter(req, res);
    }
}

复杂表达式处理(可选)

如果@PreAuthorize使用hasAnyAuthority等多权限表达式,可调整解析逻辑:

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

// ... 其他代码
if (preAuthorize != null) {
    String expression = preAuthorize.value();
    // 解析hasAnyAuthority('AUTH1','AUTH2')格式
    Pattern anyPattern = Pattern.compile("hasAnyAuthority\\(([^)]+)\\)");
    Matcher anyMatcher = anyPattern.matcher(expression);
    if (anyMatcher.find()) {
        String authStr = anyMatcher.group(1);
        String[] authorities = authStr.replace("'", "").split(",");
        for (String auth : authorities) {
            System.out.println("所需权限:" + auth.trim());
        }
    }
}

注意事项

  • 确保AuthTokenFilter被Spring容器管理(添加@Component注解),并配置合理的过滤器执行顺序。
  • 若表达式逻辑复杂,建议使用Spring的SpelExpressionParser进行专业解析,避免正则匹配的局限性。

内容的提问来源于stack exchange,提问作者Beno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:45:41