Как разрешить 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());
  }

}