Java 如何在Spring安全性中忽略端点?

Java 如何在Spring安全性中忽略端点?,java,spring-security,Java,Spring Security,我正在尝试实现JWT。我有两个端点:/api/auth/signin用于返回生成的JWT令牌的身份验证,以及/api/auth/me应基于标头中的JWT令牌返回用户。我正在尝试将Spring Security配置为仅允许授权用户访问/api**,我需要排除/api/auth/signin 下面是类中的一个configure()方法,该类扩展了websecurityConfigureAdapter: @Override protected void configure(HttpSecurity h

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

@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/sign
调用JwtAuthorizationFilter。我还试图通过以下方式忽略此端点:

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

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

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

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

我不确定是否可以从中返回生成的令牌 响应正文中JWTLoginFilter中的成功身份验证()

示例返回响应的授权标头中的令牌。但是如果你想把代币放在身体里。您可以使用以下代码:

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);
    }

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

  • 授权API:“/API/auth/**”
  • 未经授权的API:“/API/noauth/**”

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

    调用/api/auth/sign端点时是否确实使用POST请求?此外,登录端点是否可能将您重定向到其他端点?重定向过程中是否调用了过滤器?@Selindek,是的,使用了POST请求。但即使我删除了HttpMethod.POST,它仍然会调用JwtAuthorizationFilter。它不会重定向到另一个端点。UsernamePasswordAuthenticationFilter在JWT filter之前参与吗?@RahulVedpathak,不,这个筛选器在JWT filter之前没有参与。我认为你应该使用AuthenticationServerConfiguration和ResourceServerConfiguration,而不是手动配置JWT。我看过这篇文章,但在我的实现中,JWT令牌是在RestController中生成的,映射到/api/auth/signin,我需要让Spring安全性忽略它。我不确定是否可以从响应正文中JWTLoginFilter中的successfulAuthentication()返回生成的令牌。如果不希望,则不会为签名请求调用jwtAuthorizationFilter。你可以给你一个不同的前缀(比如不是以“api”开头的auth/signin),我还更新了我的帖子,向你展示了如何在正文中发送令牌。如果没有身份验证,资源可用,并且只有编辑需要凭据,那么它将不起作用。
    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);
        }