Как разрешить spring security response unauthorized (код http 401) при запросе uri без аутентификации
Я использую spring boot (1.2.6) и spring security(4.0.2).
конфигурация безопасности выглядит следующим образом,
@Configuration
@ConditionalOnWebApplication
@Profile("!integTest")
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSecurity
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60 * 60 * 24 * 30)
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
public static final String[] PROTECTED_RESOURCES = new String[] { "/user/abc" };
/*
* (non-Javadoc)
*
* @see org.springframework.security.config.annotation.web.configuration.
* WebSecurityConfigurerAdapter#configure(org.springframework.security.
* config.annotation.web.builders.HttpSecurity)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(PROTECTED_RESOURCES)
.hasRole("USER")
.anyRequest()
.permitAll()
.and()
.anonymous().disable();
}
}
однако Spring Security framework отвечает 403 (Доступ запрещен) , когда анонимный пользователь обращается к защищенному ресурсу ( / пользователь / abc).
мне интересно, как настроить spring для ответа HTTP 401 код, когда анонимный пользователь обращается к защищенному url.
Ниже приведен журнал после настройка
4 ответов
обновите версию Spring Boot до 1.3.0.Отпустите, и вы получите Http401AuthenticationEntryPoint
бесплатно. Настройте точку входа проверки подлинности в конфигурации безопасности следующим образом:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(PROTECTED_RESOURCES)
.hasRole("USER")
.anyRequest()
.permitAll()
.and()
.anonymous().disable()
.exceptionHandling()
.authenticationEntryPoint(new org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint("headerValue"));
}
и Spring Boot вернется HTTP 401
:
Status Code: 401 Unauthorized
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
WWW-Authenticate: headerValue
X-Content-Type-Options: nosniff
x-xss-protection: 1; mode=block
в весенней загрузке 2 больше нет Http401AuthenticationEntryPoint
, вместо этого вы можете использовать HttpStatusEntryPoint, который возвращает ответ с соответствующим статусом
http
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
вы не настроили аутентификацию (форма Login, HTTP Basic,...) таким образом, по умолчанию AuthenticationEntryPoint
см. Spring Security API:
задает
AuthenticationEntryPoint
использовать., если не
authenticationEntryPoint(AuthenticationEntryPoint)
указан, тоdefaultAuthenticationEntryPointFor(AuthenticationEntryPoint, RequestMatcher)
будет использоваться. ПервыйAuthenticationEntryPoint
будет использоваться, поскольку по умолчанию совпадений не найдено.если это не предусмотрено по умолчанию:
Http403ForbiddenEntryPoint
.
вы можете установить AuthenticationEntryPoint
Как написал @ksokol или настройте аутентификацию, которая определяет AuthenticationEntryPoint
.
вам нужно расширить AuthenticationEntryPoint, чтобы сделать настройку на основе исключений или причины сбоя аутентификации.
@ControllerAdvice
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
// 401
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed");
}
@ExceptionHandler (value = {AccessDeniedException.class})
public void commence(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
// 403
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authorization Failed : " + accessDeniedException.getMessage());
}
@ExceptionHandler (value = {Exception.class})
public void commence(HttpServletRequest request, HttpServletResponse response,
Exception exception) throws IOException {
// 500
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error : " + exception.getMessage());
}
}
укажите вышеуказанную пользовательскую AuthenticationEntryPoint в SecurityConfig, как показано ниже:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity (prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new MyAuthenticationEntryPoint());
}
}