【问题标题】:With Spring Security how do i determine if the current api request should be authenticated or not?使用 Spring Security,我如何确定当前的 api 请求是否应该经过身份验证?
【发布时间】:2020-09-15 19:49:00
【问题描述】:

使用 Spring Security,您可以拥有每个人都可以访问的公共 api 端点以及需要在获得响应之前进行身份验证的端点。在我的应用程序中,用户通过 jwt 令牌进行身份验证。对于现在登录的用户,始终检查令牌,无论公共 api 端点是否收到请求。

我想知道如何检查当前端点是公共端点还是经过身份验证的端点,这样我可以更改代码,以便仅在端点需要身份验证时进行令牌检查。

我可以在哈希集中添加所有公共端点并将当前请求端点与公共端点进行比较,但这效率不高,而且一些公共端点包含通配符 (**),因此比较有点很麻烦。

这是我能找到的唯一信息:

Spring Security - check if web url is secure / protected

但它是关于 JSP 的。

我也无法从SecurityContextHolder.getContext() 获取请求信息。我的猜测是我应该从org.springframework.security.config.annotation.web.builders.HttpSecurity 获取信息,因为这是用于定义哪些端点不需要身份验证的同一类。 (使用 anthMatchers().permitall())。但我不知道调用哪个方法,我不确定 HttpSecurity 是否可以自动装配到另一个类中。谁能指点一下?

谢谢

【问题讨论】:

  • 忽略未认证的端点不是更好吗?喜欢在configure(WebSecurity web) 中使用web.ignoring().antMatchers 吗?
  • 我刚刚尝试过,但没有帮助,而且它会使一些过滤器被调用两次。
  • 如果您的过滤器带有@Bean 注释,它将被调用两次。它被插入到弹簧上下文中。
  • 没有用@WebFilter 注释

标签: spring-boot spring-security jwt


【解决方案1】:

假设您使用单独的过滤器进行令牌检查,您可以通过覆盖 JwtTokenFilter 中的 OncePerRequestFilter 的 protected boolean shouldNotFilter(HttpServletRequest request) 方法来避免公共端点的令牌检查.默认情况下,此方法将始终返回 false。所以所有的请求都会被过滤掉。覆盖此方法以为公共端点返回 true 将为您提供所需的功能。 要使用通配符(**)检查请求,您可以使用 AntPathRequestMatcher。因此,您可以执行以下操作。

public class JwtTokenFilter extends OncePerRequestFilter {
    private static RequestMatcher requestMatcher;

    public static void ignorePatterns(String... antPatterns) {
        List<RequestMatcher> matchers = new ArrayList<>();
        for (String pattern : antPatterns) {
            matchers.add(new AntPathRequestMatcher(pattern, null));
        }
        requestMatcher = new OrRequestMatcher(matchers);
    }

    static {
        final String[] publicEndPoints = {"/public-api/**","/resources/**"};
        ignorePatterns(publicEndPoints);
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return requestMatcher.matches(request);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
    ....
    }
}

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2016-12-29
    • 2015-10-28
    • 2014-12-20
    • 2017-09-21
    • 2015-08-09
    • 2017-05-10
    • 1970-01-01
    • 2018-04-06
    • 2023-03-27
    相关资源
    最近更新 更多