Весенняя загрузка и весенняя безопасность, не удается отправить ошибку с пользовательским сообщением в AuthenticationEntryPoint

#java #spring #spring-boot

#java #весна #весенняя загрузка

Вопрос:

Я работаю над restful api с использованием spring boot и собираюсь использовать пользовательскую AuthenticationEntryPoint. Вот код

 @Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
    @Override
    public void commence(HttpServletRequest httpServletRequest,
                         HttpServletResponse httpServletResponse,
                         AuthenticationException e) throws IOException, ServletException {
        logger.error("Responding with unauthorized error. Message - {}", e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
    }
}
  

И соответствующую часть в конфигурации безопасности.

 @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        securedEnabled = true,
        jsr250Enabled = true,
        prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
   ...

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .exceptionHandling()
                    .authenticationEntryPoint(unauthorizedHandler)
                    .and()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                .authorizeRequests()
                    .antMatchers(HttpMethod.GET, "/api/**").permitAll()
                    .antMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
                    .antMatchers(HttpMethod.GET, "/api/users/checkUsernameAvailability", "/api/users/checkEmailAvailability").permitAll()
                .anyRequest().authenticated();

        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }
    ...
}

  

Проблема в том, что когда я вхожу в систему с неправильными учетными данными, сообщение об ошибке пустое.

 {
    "timestamp": "2020-09-03T17:16:28.082 00:00",
    "status": 401,
    "error": "Unauthorized",
    "message": "",
    "path": "/api/auth/signin"
}
  

Однако регистратор печатает правильное сообщение

 c.m.p.s.JwtAuthenticationEntryPoint      : Responding with unauthorized error. Message - Bad credentials
  

Что здесь может пойти не так? Заранее благодарю вас.

Ответ №1:

Значение по умолчанию для server.error.include-message равно "never" .

Поэтому вам просто нужно настроить свой application.yaml (или свойства) следующим образом

 server:
  error:
    include-message: always
    include-binding-errors: always
  

Комментарии:

1. Следующий вопрос, я вижу, что другие проекты Spring не вызывают этого, но сообщение об ошибке продолжается. Почему они могут отправлять сообщение об ошибке без настройки?

2. @MillerDong Это зависит от того, какая версия spring boot используется в проекте. Начиная с Spring Boot 2.3, они изменили значение по умолчанию server.error.include-message на never