401 вместо 403 с Spring Boot 2
С помощью Spring Boot 1.5.6.RELEASE мне удалось отправить код состояния HTTP 401
вместо 403
как описано в разделе Как разрешить несанкционированный ответ безопасности Spring (код http 401), если запрашивает URI без аутентификации, сделав это:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//...
http.exceptionHandling()
.authenticationEntryPoint(new Http401AuthenticationEntryPoint("myHeader"));
//...
}
}
с использованием org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint
учебный класс.
Я только что обновился до Spring Boot 2.0.0.RELEASE и обнаружил, что такого класса больше нет (по крайней мере, в этом пакете).
Q: это класс (Http401AuthenticationEntryPoint
) есть еще в Spring Boot? Если нет, что может быть хорошей альтернативой для сохранения того же поведения в существующем проекте, чтобы сохранить согласованность с другими реализациями, которые зависят от этого кода состояния (401
) вместо 403
?
5 ответов
Класс org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint
был удален в пользу org.springframework.security.web.authentication.HttpStatusEntryPoint
,
В моем случае код будет выглядеть так:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//...
http.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
//...
}
}
Просто чтобы разработать ответ @lealceldeiro:
До Spring Boot 2 мой класс конфигурации Securiy выглядел так:
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {
@Bean
public Http401AuthenticationEntryPoint securityException401EntryPoint() {
return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
}
@Autowired
private Http401AuthenticationEntryPoint authEntrypoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
// some http configuration ...
// Spring Boot 1.5.x style
http.exceptionHandling().authenticationEntryPoint(authEntrypoint);
}
//...
}
А теперь в Spring Boot 2 это выглядит так:
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {
//Bean configuration for Http401AuthenticationEntryPoint can be removed
//Autowiring also removed
@Override
protected void configure(HttpSecurity http) throws Exception {
// some http configuration ...
// Spring Boot 2 style
http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
}
//...
}
Смотрите также здесь: https://github.com/spring-projects/spring-boot/issues/10715
Http401AuthenticationEntryPoint
был удален, см. 10715:
Удалить Http401AuthenticationEntryPoint
rwinch прокомментировал 20 октября 2017
Насколько я могу судить, он не используется в базе кода Spring Boot, поэтому может быть полезно удалитьHttp401AuthenticationEntryPoint
,
В зависимости от ваших требований вы можете использовать:
Для реактивного (WebFlux) стека вы можете переопределить возвращаемый код состояния, добавив такой @Bean для перехвата некоторых конкретных исключений:
@Component
class MyErrorAttributes : DefaultErrorAttributes() {
override fun getErrorAttributes(
request: ServerRequest,
options: ErrorAttributeOptions
): MutableMap<String, Any> {
val cause = super.getError(request)
val errorAttributes = super.getErrorAttributes(request, options)
when (cause) {
is TokenExpiredException -> {
errorAttributes["status"] = HttpStatus.UNAUTHORIZED.value()
errorAttributes["error"] = HttpStatus.UNAUTHORIZED.reasonPhrase
}
}
return errorAttributes
}
}
Вы можете настроить свою логику с переопределением класса AuthenticationEntryPoint, это должно работать:
@Component public class AuthEntryPointException implements AuthenticationEntryPoint, Serializable {
private static final long serialVersionUID = -8970718410437077606L;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write("{\"result\":\"UNAUTHORIZED\",\"message\":\"UNAUTHORIZED or Invalid Token\"}");
}
}