Search code examples
springspring-bootspring-security

Spring Security 6: 401 Unauthorized request


I have this security configuration:

package io.chernikov.registerme.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * Security configuration class.
 *
 * @author Serhii Chernikov
 * @version 1.0
 */
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .cors(AbstractHttpConfigurer::disable)
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorization -> {
                    authorization.requestMatchers("/registration/**").permitAll();
                })
                .authorizeHttpRequests(authorization -> {
                    authorization.requestMatchers("/users/**")
                            .hasAnyAuthority("USER", "ADMIN");
                })
                .httpBasic(Customizer.withDefaults())
                .formLogin(Customizer.withDefaults())
                .build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Here is my RegistrationController:

package io.chernikov.registerme.registration.controller;

import io.chernikov.registerme.event.RegistrationCompleteEvent;
import io.chernikov.registerme.registration.model.RegistrationRequest;
import io.chernikov.registerme.user.model.User;
import io.chernikov.registerme.user.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;

/**
 * Registration REST controller implementation class.
 *
 * @author Serhii Chernikov
 * @version 1.0
 */
@RequiredArgsConstructor
@RestController
@RequestMapping(path = "/registration")
public class RegistrationController {

    private final UserService userService;
    private final ApplicationEventPublisher eventPublisher;

    @PostMapping(path = "/")
    public User register(@RequestBody RegistrationRequest request, final HttpServletRequest servletRequest) {
        User user = userService.registerUser(request);
        eventPublisher.publishEvent(new RegistrationCompleteEvent(user, getApplicationUrl(servletRequest)));

        return user;
    }

    @GetMapping(path = "/verification")
    public String verify(@RequestParam String token) {
        return null; // TODO: implement this
    }

    private String getApplicationUrl(HttpServletRequest request) {
        return String.format("http://%s:%s%s", request.getServerName(),
                                               request.getServerPort(),
                                               request.getContextPath());
    }

}

When I start the app and try to send a POST request on http://localhost:8080/registration I get 401: Unauthorized response (although it seems to me that I permitted unauthorized requests to /registration/**).

Maybe I did something wrong in the config?


Solution

  • No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint

    In your controller, the path does not match the endpoint of the request. Remove the slash in the path to match the endpoint: http://localhost:8080/registration

    @PostMapping()
        public User register(@RequestBody RegistrationRequest request, final HttpServletRequest servletRequest) {}
    

    You can keep your code but you must use this endpoint: http://localhost:8080/registration/