All my GET
requests works fine with authorized access but, all my POST
requests are returned with 401 unauthorized access and I am using Basic authorization with username and password, I guess the problem is emerging from CSRF token but I have disabled and nothing happens.
我所有的GET请求在授权访问下都工作得很好,但是,我所有的POST请求都返回了401个未经授权的访问,我使用的是用户名和密码的基本授权,我猜问题是从CSRF令牌出现的,但我已经禁用了,什么也没有发生。
Below is my SecurityConfig
class
下面是我的SecurityConfig类
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
//.cors(Customizer.withDefaults())
.csrf((csrf) -> csrf.disable())
.authorizeHttpRequests((authz) -> authz
.requestMatchers(HttpMethod.GET, "/api/**").permitAll()
//.requestMatchers(HttpMethod.POST, "/api/**").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
@Bean
public UserDetailsService users() {
// The builder will ensure the passwords are encoded before saving in memory
//User.UserBuilder users = User.withDefaultPasswordEncoder();
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("pass"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
and this is my controller
这是我的控制器
@PreAuthorize("hasRole(ADMIN)")
@PostMapping
public ResponseEntity<PostDto> createPost(@Valid @RequestBody PostDto postDto) {
return new ResponseEntity<>(postService.createPost(postDto), HttpStatus.CREATED);
}
and these are my logs
这些是我的日志
2023-09-10T23:55:35.850+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/api/posts
2023-09-10T23:55:35.850+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
2023-09-10T23:55:35.851+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : Securing POST /error
2023-09-10T23:55:35.851+02:00 DEBUG 20476 --- [nio-8080-exec-7] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using Or [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest], And [Not [MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[*/*]]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@379dbd63, matchingMediaTypes=[*/*], useEquals=true, ignoredMediaTypes=[]]]
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint@7ca4ed9f
2023-09-10T23:55:35.852+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2023-09-10T23:55:35.853+02:00 DEBUG 20476 --- [nio-8080-exec-7] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@74626aab
Spring boot v3.1.2
Spring Boot v3.1.2
If someone can help, I'd appreciate.
如果有人能帮忙,我将不胜感激。
更多回答
Your question is confusing me, you mention POST requests not working, but you're showing the PUT method in your controller and you have commented out the .requestMatchers(HttpMethod.POST, "/api/**").permitAll()
in your security configuration. Perhaps that's one of your errors?
您的问题让我感到困惑,您提到POST请求不起作用,但是您在控制器中显示了PUT方法,并且在安全配置中注释掉了.questMatcher(HttpMethod.POST,“/api/**”).permitAll()。也许这是你的错误之一?
Sry for this confusion, I have edited the correct controller method, and about commenting this line I have tried executing it before and it doesn't resolve the problem @voidvoid
SRY对于这种混淆,我已经编辑了正确的控制器方法,并且关于注释此行,我以前曾尝试执行它,但它没有解决问题@voidvoid
Can you add the @Bean
annotation above your public SecurityFilterChain filterChain(HttpSecurity http)
function. I believe your configuration is not being picked up at all.
您能否将@Bean注释添加到您的公共SecurityFilterChain(HttpSecurity Http)函数之上。我相信您的配置根本不会被采用。
It worked!! after adding @Bean annotation, thank you! if you can please tell me why this was so important and if it is should I add it in every single method in Spring boot or what?
成功了!!添加@Bean注释后,谢谢!如果您能告诉我为什么这是如此重要,如果是的话,我应该将它添加到Spring启动的每个方法中吗?
Simply defining the method in your configuration class is not enough. Spring security has a default security filter chain, and if you want to override some behavior you have to provide your own bean.
在配置类中简单地定义方法是不够的。Spring安全有一个默认的安全筛选器链,如果您想覆盖某些行为,则必须提供您自己的Bean。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) { ... }
The @Bean
annotation is necessary because you want to communicate "here, use this method to create a SecurityFilterChain bean". Once the bean is present in the context, it will be automatically picked up.
@Bean注释是必需的,因为您希望“在这里,使用此方法创建一个SecurityFilterChain Bean”。一旦Bean出现在上下文中,它将被自动拾取。
To answer your question "should I add it in every single method in Spring boot or what?":
No, you should not. You add it when you want to specify that your method returns a bean to be managed by the spring context. Often you will be configuring some aspect of spring using this method, but in general your methods don't return beans.
回答您的问题“我应该在Spring Boot的每个方法中都添加它吗?”:不,您不应该这样做。当您想要指定您的方法返回一个由Spring上下文管理的Bean时,可以添加它。通常,您将使用此方法配置Spring的某些方面,但通常您的方法不返回Bean。
更多回答
我是一名优秀的程序员,十分优秀!