DarkChyper
DarkChyper

Reputation: 25

Spring Security antMatcher with HttpMethod.POST does not work

Edit :

Thx Thomas Andolf ! It works when i use embended tomcat in springboot 'spring i launched on IntelliJ and the angular part with visual studio code. But it does not work when i publish the war in provided tomcat on my raspberry pi...

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests(authorizeRequests ->
                        authorizeRequests.antMatchers(HttpMethod.POST, "/rest/gender").permitAll()
                        .antMatchers(HttpMethod.POST, "/rest/login").permitAll()
                        .antMatchers(HttpMethod.POST, "/rest/names").permitAll()
                        .anyRequest().authenticated()
                )
                .httpBasic()
                .authenticationEntryPoint(authEntryPoint)
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

The angular part of the project is published in tomcat/webapps/ROOT.
The war is published in tomcat/webapps/baby-project-api.

I use tomcat/conf/Catalina/localhost/rewrite.config like this :

RewriteRule ^/rest/(.+)$ /baby-project-api/rest/$1

Original Question

I try to use Basic Authentication on an api with spring boot security and i need some path to be not secured.

POST /rest/login is not secured with the config,
GET /rest/gender is secured and that's what i want

Any idea why POST /rest/gender is still secured ?

There is my WebSecurityConfig :

@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationEntryPoint authEntryPoint;

    @Autowired
    private IParentRepository parentRepository;

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/rest/gender").permitAll()
                .antMatchers(HttpMethod.POST, "/rest/login").permitAll()
                .antMatchers(HttpMethod.POST, "/rest/names").permitAll()
                .anyRequest().authenticated()
                .and().httpBasic()
                .authenticationEntryPoint(authEntryPoint);
                //.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        final List<Parent> parents = parentRepository.findAll();
        InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> mngConfig = auth.inMemoryAuthentication();

        for (Parent parent : parents) {
            mngConfig.withUser(User.withUsername(parent.getUsername()).password(parent.getPassword()).roles("ADMIN").build());
        }

    }
}```

POST /rest/login is not secured with the config,  
GET /rest/gender is secured and that's what i want

Any idea why POST /rest/gender is still secured ?

Upvotes: 0

Views: 3071

Answers (2)

DarkChyper
DarkChyper

Reputation: 25

After all, i did not find a great solution by this way.

i open all the api and restricted some parts with pre-auth :

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .anyRequest().permitAll()
            .and().httpBasic()
            .authenticationEntryPoint(authEntryPoint)
            .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

And on the controller :

@RestController
@PreAuthorize("isAuthenticated()")
@RequestMapping("/rest/gender")
public class GenderController {

[...]
// protected by the @ on the class
@GetMapping(value = "")
    public List<Gender> listerGender(final SecurityContextHolderAwareRequestWrapper request){
        return genderService.listerGender(request);
    }

 @PreAuthorize("permitAll()")
    @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Void> creerGender(@Valid @RequestBody Gender gender){
        return this.genderService.creerGender(gender);
    }

I think we can make it cleaner but at least it works

Upvotes: 0

Toerktumlare
Toerktumlare

Reputation: 14732

can you please try doing it the way they actually do it in the documentation and see if it works.

protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests(authorizeRequests -> 
                authorizeRequests.antMatchers(HttpMethod.POST, "/rest/gender").permitAll();
                authorizeRequests.antMatchers(HttpMethod.POST, "/rest/login").permitAll();
                authorizeRequests.antMatchers(HttpMethod.POST, "/rest/names").permitAll();
                authorizeRequests.anyRequest().authenticated();
            )
            .httpBasic()
            .authenticationEntryPoint(authEntryPoint);
}

Upvotes: 1

Related Questions