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.