401 Несанкционированный доступ к AuthenticationManager.authenticate() (Spring Security)

#spring #spring-boot #spring-security

#spring #весенняя загрузка #spring-безопасность

Вопрос:

401 Несанкционированный, созданный при попытке входа в систему во время регистрации, работает отлично.

Во время отладки я заметил, что ответ дается в строке, где вызывается метод authenticationManager.authenticate() at UserController . Еще одна вещь, которую я заметил, это то, что по какой-то причине у меня не было этой проблемы при работе с репозиториями JPA, а не с DAO. Я использую PostgreSQL

введите описание изображения здесь

Вот код для соответствующего метода, если UserController :

     @RequestMapping(path = "/auth", method = RequestMethod.POST)
    @ResponseStatus(value = HttpStatus.OK)
    public AuthResponse authenticate(@RequestBody AuthRequest req){
        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(req.getUsername(), req.getPassword()));
        String token = jwtService.generateToken(req.getUsername());
        return new AuthResponse(token);
    }
  

JwtFilter.doFilterInternal():

     @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String authorizationHeader = httpServletRequest.getHeader("Authorization");
        String jwtToken = null;
        String username = null;
        if (authorizationHeader != null amp;amp; authorizationHeader.startsWith("Bearer")) {
            jwtToken = authorizationHeader.substring(7);
            username = jwtService.extractUsername(jwtToken);
        }
        if (username != null amp;amp; SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (jwtService.validateToken(jwtToken, userDetails.getUsername())) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities()
                );
                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
  

SecurityConfig.configure():

     @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().cors().disable()
                .authorizeRequests()
                .anyRequest().permitAll()
                .and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().httpBasic();
    }
  

UserService.loadUserByUsername():

 @Service
public class UserService implements IUserService, UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User userByName = userDao.getUserByUsername(s);
        return new org.springframework.security.core.userdetails.User(userByName.getUsername(), userByName.getPassword(), userByName.getAuthorities());
    }
}
  

Запрос DAO:

 @Override
public User getUserByUsername(String username) {
    return jdbcTemplate.queryForObject("SELECT * FROM user_table WHERE username = ?", new Object[]{username}, User.class);
}
  

Ответ №1:

Вероятно, это проблема JWT. В строке: .and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) используйте отладку, чтобы посмотреть, что у вас там есть в качестве параметров.

Ответ №2:

Если вы посмотрите на документацию :

 An AuthenticationManager must honour the following contract concerning exceptions:

A DisabledException must be thrown if an account is disabled and the AuthenticationManager can test for this state.
A LockedException must be thrown if an account is locked and the AuthenticationManager can test for account locking.
A BadCredentialsException must be thrown if incorrect credentials are presented. Whilst the above exceptions are optional, an AuthenticationManager must always test credentials.
Exceptions should be tested for and if applicable thrown in the order expressed above (i.e. if an account is disabled or locked, the authentication request is immediately rejected and the credentials testing process is not performed). This prevents credentials being tested against disabled or locked accounts.
  

Я предполагаю, что ваша проверка подлинности выдает одно из этих трех исключений (или, возможно, какое-то другое исключение). Вам нужно просмотреть свои журналы, чтобы определить, какой из них, или перехватить исключение и отладить его.

Ответ №3:

Проблема заключалась в том, что запрос не вернул ожидаемое значение. Я изменил:

  @Override
public User getUserByUsername(String username) {
    List<User> userList = jdbcTemplate.query("SELECT * FROM user_table WHERE username = ?", new Object[]{username}, (resultSet,i) -> {
        System.out.println(1);
        return new User(resultSet.getInt("id"),
                resultSet.getString("username"),
                resultSet.getString("password"),
                resultSet.getString("role"));
    });
    return userList.get(0);
}