我还没有找到一个合适的解决方案来解决我的问题。我使用Spring Security Oauth2资源服务器来验证我的请求。它工作正常。但是当用不同的场景测试时,我们发现如果没有***Authorization***头,或者如果有Authorization头但值不是以***Bearer***开始,Spring Security返回403而不是401。
Spring Boot Starter - 2.6.7
Spring Boot Starter Security - 2.6.7
Spring Security Config & Web - 5.6.3
Spring Security Core - 5.3.19
Spring Boot Starter OAuth2 Resource Server - 2.6.7
Spring OAuth2 Resource Server - 5.6.3
我指的是this answer,并在下面添加了 BearerTokenAuthenticationEntryPoint 的代码。不同之处在于我使用的是内省url而不是jwt。但这没有帮助,该部分不会被执行。如果存在Bearer令牌,则只有它会被执行。
我错过了什么?
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class CustomResourceServerSecurityConfiguration {
@Value("${spring.security.oauth2.resourceserver.opaque-token.introspection-uri}")
String introspectionUri;
@Value("${spring.security.oauth2.resourceserver.opaque-token.client-id}")
String clientId;
@Value("${spring.security.oauth2.resourceserver.opaque-token.client-secret}")
String clientSecret;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2
.opaqueToken(opaque -> opaque.introspectionUri(this.introspectionUri)
.introspectionClientCredentials(this.clientId, this.clientSecret))
.authenticationEntryPoint((request, response, exception) -> {
System.out.println("Authentication failed");
BearerTokenAuthenticationEntryPoint delegate = new BearerTokenAuthenticationEntryPoint();
delegate.commence(request, response, exception);
}))
.exceptionHandling(
(exceptions) -> exceptions.authenticationEntryPoint((request, response, exception) -> {
System.out.println("Authentication is required");
BearerTokenAuthenticationEntryPoint delegate = new BearerTokenAuthenticationEntryPoint();
delegate.commence(request, response, exception);
}));
return http.build();
}
}
3条答案
按热度按时间42fyovps1#
如果您的场景是,在缺少Bearer令牌的情况下,POST得到403,GET得到401,这与csrf有关。
44.2.14我在执行POST时得到403禁止
如果针对HTTP POST传回HTTP 403 Forbidden,但对HTTP GET有效,则问题很可能与CSRF有关。请提供CSRF记号或停用CSRF保护(不建议使用)。
这是来源
如果您使用JWT标记,那么如果没有任何其他要求,那么您可以禁用它。
4.无状态Spring API
如果我们的无状态API使用基于令牌的身份验证(如JWT),我们就不需要CSRF保护,并且必须像前面看到的那样禁用它
Source
wb1gzix02#
使用默认配置时,当授权头丢失或无效(格式错误、过期、错误的颁发者等)时,您应该有一个302(重定向到登录)。如果您有一个403,那么您将面临另一个异常(CSRF、CORS或其他)。设置
logging.level.org.sprngframework.security=DEBUG
并仔细检查日志要更改此默认行为(401而不是302),请按照those tutorials中的方式进行操作:
在the one for servlets and token introspection这样的示例中,它完全符合您的用例,您甚至可以找到Asserthttp状态是您所期望的状态的单元测试:未授权时为401,拒绝时为403:
当然,那些测试通过了...
j1dl9f463#
我做的更改是,删除了 @EnableWebSecurity 注解,并使用 WebSecurityConfigurerAdapter 扩展了类,并使用相同的内容覆盖了 configure(HttpSecurity)。
我的最后一堂课如下。