When I try to make request to opened endpoint /v1/register I get 401 Unauthorized or 403 Forbidden instead 2xx answer.
curl --request POST \
--url http://localhost:8080/v1/register \
--header 'Content-Type: application/json' \
--data '{
"email": "kotik2@yandex.ru",
"password": "12345"
}'
Code of security config with corresponding matchers package net.neurosystems.mlapi.config;
import net.neurosystems.mlapi.dao.UserRepository;
import net.neurosystems.mlapi.service.UserDetailServiceImpl;
import net.neurosystems.mlapi.service.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
private final UserRepository userRepository;
@Autowired
public SecurityConfig(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(new UserDetailServiceImpl(userRepository))
.passwordEncoder(encoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/v1/**").authenticated().and().httpBasic().and()
.authorizeRequests()
.antMatchers("/v1/register").permitAll();
}
}
pom xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>net.neurosystems</groupId>
<artifactId>mlapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mlapi</name>
<description>mlapi</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
The question/bug is why are requests to endpoint /v1/register require authorization despite of permitAll instruction?
Comment From: terminux
Your /v1/register endpoint will be overwritten by the previous /v1/** configuration.
Maybe you can modify the configuration to:
http
.authorizeRequests()
.antMatchers("/v1/register").permitAll().and()
.authorizeRequests()
.antMatchers("/v1/**").authenticated().and().httpBasic();
Comment From: DenisovaElena
Thanks for your answer, I tried to solve it this way, but it doesn't work. It works only with this work around code
``` @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/v1/**").authenticated().and().httpBasic().and() .authorizeRequests() .antMatchers("/v1/register").permitAll(); }
@Override
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/v1/register");
}
But this is not proper way.
**Comment From: terminux**
If you use the command line to access your application, you may need to disable `csrf`.
The configuration may be like this:
```java
http.csrf().disable()
.authorizeRequests()
.antMatchers("/v1/register").permitAll().and()
.authorizeRequests()
.antMatchers("/v1/**").authenticated().and().httpBasic();
Comment From: eleftherias
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add a minimal sample that reproduces this issue if you feel this is a genuine bug.
Comment From: Adarshv194
This will resolve the issue: main thing to include is .csrf().disable()
http.authorizeRequests() .antMatchers("/your url").anonymous() .anyRequest().authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .csrf().disable() .formLogin();
Comment From: uniquejava
So many pitfalls, I hope spring security would add a default config for REST APIs (token only) where csrf disabled by default, and session is disabled by default, and with built-in jwt/opaque token endpoint, and some BearerTokenFilter built-in, so on and so forth.
with something like the following!
http
.restApi(rest-> rest.enable())
.token(token->token.tokeType(opaque|jwt))
build();
This would make life much easier in these days when every application is using react/angular/vue.
Comment From: ShaunAUS
Does anyone resolve this issue in proper way?? cuz the answers that i got from here , doesn' work for me... ( i got same issue now)
Comment From: akifHasdemir
Does anyone resolve this issue in proper way?? cuz the answers that i got from here , doesn' work for me... ( i got same issue now)
Did you solve the issue?
Comment From: ShaunAUS
Does anyone resolve this issue in proper way?? cuz the answers that i got from here , doesn' work for me... ( i got same issue now)
Did you solve the issue?
sosrry mate i don't remember
Comment From: yayen-lin
I gave up on using permitAll() and a workaround I found was using web.ignoring()
So an example would be
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/**");
}
}
(I'm also new so please correct me if I'm wrong)
Comment From: baiglin
Hi all,
I ran into the same issue lately. After lot of debugging, I could see that I had more SecurityFilterChain than expected in the FilterChainProxy.
One was coming from sprin-boot-actuator ManagementWebSecurityAutoConfiguration, even though it contains @ConditionalOnDefaultWebSecurity.
I excluded it, but then it came from SpringBootWebSecurityConfiguration.SecurityFilterChainConfiguration that also contains @ConditionalOnDefaultWebSecurity...
@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
static class SecurityFilterChainConfiguration {
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
http.formLogin();
http.httpBasic();
return http.build();
}
I did not dig more on why the condition is not respected, still I tried two things that worked: - adding a @Order with a higher priority than @Order(SecurityProperties.BASIC_AUTH_ORDER) - renaming my bean to defaultSecurityFilterChain
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
LOG.info("Configure security");
http.formLogin().disable()
.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll());
return http.build();
}
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
LOG.info("Configure security");
http.formLogin().disable()
.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll());
return http.build();
}
In this case, my filter chain was picked up first and applied the necessary parameters.