如何在Spring Security中忽略端点?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Spring Security中忽略端点?相关的知识,希望对你有一定的参考价值。

我正在尝试实施JWT。我有两个端点:用于身份验证的/api/auth/signin返回生成的JWT令牌,/api/auth/me应该根据头中的JWT令牌返回用户。我正在尝试将Spring Security配置为仅授权用户访问/api**,我需要排除/api/auth/signin这是一个扩展configure()的类的WebSecurityConfigurerAdapter方法:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/api**")
            .httpBasic().disable()
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/api/auth/signin").permitAll()
                .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
}

但它仍然为/api/auth/signin调用JwtAuthorizationFilter。我还试图忽略这个端点:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.POST,"/api/auth/signin");
}

有没有其他方法可以忽略它或者permitAll()ignoring()应该以不同的方式使用?

答案

您需要一个AbstractAuthenticationProcessingFilter过滤器,用于在/ api / auth / signin上生成JWT令牌,以及一个GenericFilterBean,用于检索身份验证对象并将其放入SecurityContextHolder中

以下链接中有一个很好的示例:

https://auth0.com/blog/securing-spring-boot-with-jwts/

http.antMatcher("/api**")
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            // We filter the api/login requests
            .addFilterBefore(new JWTLoginFilter("/api/auth/signin", authenticationManager()),
                    UsernamePasswordAuthenticationFilter.class)
            // And filter other requests to check the presence of JWT in header
            .addFilterBefore(new jwtAuthorizationFilter(),
                    UsernamePasswordAuthenticationFilter.class);

而且我不确定是否可以从响应正文中的JWTLoginFilter中的successfulAuthentication()返回生成的令牌

该示例返回响应的Authorization标头中的标记。但是如果你想在体内返回令牌。你可以使用以下代码:

static void addAuthentication(HttpServletResponse res, String username) {
        String JWT = Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
//        res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
        JSONObject tokenJson = new JSONObject();
        tokenJson.put(SecurityConstants.JWT_TOKEN, JWT);
        tokenJson.put(SecurityConstants.USERNAME, username);
        try(PrintWriter writer = res.getWriter()) {
            writer.print(tokenJson.toJSONString());
            writer.flush();
        } catch (IOException e) {
            LOG.error("error ...");
        }
//        res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
    }
另一答案

为什么不创建两种类型的端点:

  1. 授权的API:“/ api / auth / **”
  2. 未经授权的API:“/ api / noauth / **”

然后仅为“/ api / auth / **”配置安全性

以上是关于如何在Spring Security中忽略端点?的主要内容,如果未能解决你的问题,请参考以下文章

如何在spring boot项目中忽略特定URL的spring security CSRF

如何在spring security oauth2中分离访问令牌和刷新令牌端点

如何仅在安全端点上应用 Spring Security 过滤器?

Spring:使用Spring Security配置执行器端点的安全性

Spring Security + Keycloak 授权:如何将端点与资源相关联?

我们如何禁用 /oauth/token 的 GET 选项端点,并且只在 Spring Security 中保留 POST 选项?