Reputation: 834
I've been trying to follow this tutorial :
https://www.baeldung.com/spring-security-basic-authentication
I have created a couple of rest endpoints like this :
@RestController
public class PostController {
@Autowired
PostCommentService postCommentService;
@Autowired
PostService postService;
@GetMapping("/comment")
public PostComment getComment(@RequestParam Long id) {
return postCommentService.findPostCommentById(id);
}
@PostMapping("/createPost")
public void createPost(@RequestBody PostDTO body){
postService.createPost(body);
}
}
Now for security I am using spring like this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
This is the config class for spring security:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers( "/comment").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(passwordEncoder().encode("password"))
.authorities("ROLE_USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
The CustomFilter looks like this:
public class CustomFilter extends GenericFilterBean {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
And this is the AuthenticationEntryPoint:
@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException {
response.addHeader("WWW-Authenticate", "Basic realm= + getRealmName() + ");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 - " + authEx.getMessage());
}
@Override
public void afterPropertiesSet(){
setRealmName("spring");
super.afterPropertiesSet();
}
}
Now the problem is that whenever I try to send a POST request I end up getting this error message:
HTTP Status 401 - Full authentication is required to access this resource
I have tried two approaches to send the request, one via postman
And the second one via curl:
curl -i --user admin:password --request POST --data {"text":"this is a new Post"} http://localhost:8080/createPost
I am at my wits' end here, hence the need to create this post. Any help will be much appreciated.
This is the curl response in case it might shed light on the matter:
1.1 401 Set-Cookie: JSESSIONID=6FE84B06E90BE7F2348C0935FE3DA971; Path=/; HttpOnly X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Frame-Options: DENY WWW-Authenticate: Basic realm= + getRealmName() + Content-Length: 75 Date: Thu, 10 Sep 2020 13:47:14 GMT
HTTP Status 401 - Full authentication is required to access this resource
Upvotes: 0
Views: 3315
Reputation: 80
This happens because Spring Security comes with CSRF protection enabled by default (and for a good reason). You can read about Cross Site Request Forgery here. In your case the CsrfFilter detects missing or invalid CSRF token and you're getting the 401 response. The easiest way to make your example work would be to disable csrf-ing in your security configuration but, of course, you shouldn't do this in a real application.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers( "/comment").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
Upvotes: 1