Podczas rejestracji użytkownika - 401 unauthorized

0

Cześć,

mam problem z rejestracją użytkownika w springu. Można to zrobić dopiero po zalogowaniu użytkownika, w innym przypadku dostaję 401 Unauthorized.

UserController - rejestruję po wejściu localhost:8080/users przy użyciu POST:

@AllArgsConstructor
@CorsRestController
@RequestMapping("/users")
@Slf4j
public class UserController {

    UserRepository userRepository;
    PasswordEncoder passwordEncoder;


    @PostMapping()
    @ResponseStatus(value = HttpStatus.CREATED)
    public void createUser(@Valid @RequestBody UserDTO userDTO) throws UserFoundException {
        AppUser appUser = userRepository.findUserByEmail(userDTO.getEmail());
        if(appUser != null) {
            throw new UserFoundException();
        }
        AppUser user = AppUser.builder()
                .firstName(userDTO.getFirstName())
                .lastName(userDTO.getLastName())
                .email(userDTO.getEmail())
                .password(passwordEncoder.encode(userDTO.getPassword()))
                .roles(Arrays.asList("USER"))
                .id(UUID.randomUUID().toString()).build();
        userRepository.save(user);
    }



    @GetMapping()
    public AppUser getUser() {
        UserDetails userDetails =
                (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();  //getting user from session
        userDetails.getUsername();
        return userRepository.findUserByEmail(userDetails.getUsername());
    }


    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public void exceptionHandler(UserFoundException userFoundException) {
        log.info("brak uzytkownika");
    }


}

SpringSecurityConfig:


@Configuration
@EnableWebSecurity

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();

        http
                .httpBasic()
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/users").permitAll()
                .antMatchers(HttpMethod.POST, "/users/**").hasRole("USER")
                .antMatchers(HttpMethod.GET, "/users/**").hasRole("USER")
                .antMatchers(HttpMethod.PUT, "/users/**").hasRole("USER")
                //.anyRequest().authenticated()
                .and()
                .formLogin().disable();
    }

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

}

Ma ktoś może jakiś pomysł co tu poprawić, żeby działało jak powinno?

2

Ustawiasz logowanie na DEBUG i parzysz co tam wypluje, powinno być ładnie rozpisane jak próbował zmatchować ten request.

1

Co mi przychodzi do głowy.
POST /users, ten endpoint musi pozwalać unauthenticated users do podłączenia się.
Tutaj znalazłem coś podobnego:
https://stackoverflow.com/questions/40927732/spring-security-with-spring-boot-allowing-unauthenticated-user-access-on-specif
Tutaj jest generalnie dobry przykład:
https://dzone.com/articles/secure-a-spring-boot-app-with-spring-security-and

A tak od siebie dodam, poczytaj również o adnotacji @PreAuthorize. Ja bym zrobił oddzielny kontroler dla operacji niewymagających autentykacji. Istotna jest kolejność w tych matcherach, one się w pewien sposób nadpisują.
Jak już robisz http.csrf().disable(); to poczytaj co to jest CSRF

1

Dodaj do configure w Security wyłączenie domyślnie działających opcji Springa:

  .headers()
  .frameOptions()
  .disable()

Oczywiście dobrze byłoby poczytać co to wyłącza.

2
UserRepository userRepository;
PasswordEncoder passwordEncoder;

zrób je private i final to będzie ładniej ;)

Masz :httpBasic() i .and().formLogin().disable();, pewnie czegoś nie zauważasz. DEBUG pomoże ogarnąć co jest nie tak.

A tak przy okazji:

    @GetMapping()
    public AppUser getUser() {
        UserDetails userDetails =
                (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();  //getting user from session
        userDetails.getUsername();                                                                                // <-------------- PO CO CI TA LINIA?
        return userRepository.findUserByEmail(userDetails.getUsername());
    }

i zwracania encji na twarz? Może jakiś dto?

1 użytkowników online, w tym zalogowanych: 0, gości: 1