2015-06-04 31 views
7

Java Config ile sağlanan istekleri onaylayarak, spring security'da varsayılan davranışta bir sorunum var.Spring Security anonim 401 yerine 403

http 
     .... 
     .authorizeRequests() 
      .antMatchers("/api/test/secured/*").authenticated() 

I (anonim kullanıcı ile) giriş gerekmeden örneğin /api/test/secured/user için bir çağrı yaptığınızda, Yasak 403 döndürür. Anonim kullanıcı authenticated() veya @PreAuthorize kaynağı tarafından güvenceye almak istediğinde, 401 durumunun değiştirilememesi kolay bir yol var mı?

cevap

5

Ben çözüm here var:

http 
    .authenticationEntryPoint(authenticationEntryPoint) 

AuthenticationEntryPoint kaynak kodu: bahar güvenlik 4.x ile

@Component 
public class Http401UnauthorizedEntryPoint implements AuthenticationEntryPoint { 

    private final Logger log = LoggerFactory.getLogger(Http401UnauthorizedEntryPoint.class); 

    /** 
    * Always returns a 401 error code to the client. 
    */ 
    @Override 
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException, 
      ServletException { 

     log.debug("Pre-authenticated entry point called. Rejecting access"); 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied"); 
    } 
} 
+0

Bu çalışıyor! Teşekkür ederim. – Mati

+0

Tanklar, bu çözüm benim de sorunum için çalıştı! Bunun tersini yapmak istedim: 401 ile 403 arasında değişiklik yapmak istiyorum. kimlik doğrulaması dikiş yapıyorEntryPoint httpBasic() öğesine taşındı, bunun için bir düzenleme istedim. – switch87

13

zaten

org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint 

Bahar için sınıf var önyükleme ayrıca bir

içerir tanımladığınız güvenlik yapılandırmanızdaki Yani

HTTP/1.1 401 Unauthorized 
WWW-Authenticate: Bearer realm="example", 
        error="invalid_token", 
        error_description="The access token expired" 

ve sınıf fasulye autowire:

org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint 

ve ayarlanması gerekir 401 responses requires that header WWW-Authenticate olarak uyumlu spec kullanmak geliştirici gerektiren hem faydaları, örnek 401 yanıt olabilir

Yani bahar çizme uygulaması ile örneğin:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled=true) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ 

    @Bean 
    public Http401AuthenticationEntryPoint securityException401EntryPoint(){ 

     return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\""); 
    } 

    @Autowired 
    private Http401AuthenticationEntryPoint authEntrypoint; 
... 
@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .authorizeRequests() 
       .antMatchers("/login").anonymous() 
       .antMatchers("/").anonymous() 
       .antMatchers("/api/**").authenticated() 
      .and() 
      .csrf() 
       .disable() 
       .headers() 
       .frameOptions().disable() 
      .and() 
       .sessionManagement() 
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
      .and() 
      .logout() 
       .permitAll() 
     .exceptionHandling().authenticationEntryPoint(authEntrypoint); 
} 

ilgili çizgidir:

.exceptionHandling().authenticationEntryPoint(authEntrypoint); 
+1

Az önce yarattığınız fasulyeyi enjekte etmek yerine, doğrudan işlevi çağırabilirsiniz: '.exceptionHandling(). AuthenticationEntryPoint (securityException401EntryPoint());'. Aynı örneği alırdı, çünkü 'Bean' açıklamalı işlevlerinin çağrılması doğrulandı. – EliuX

+1

Spring Boot 2'de bu sınıf [kaldırıldı] (https://github.com/spring-projects/spring-boot/issues/10715). Sadece Spring Boot 1.5.10 kaynak denetiminden uygulamamda onu yeniden oluşturdum [ burada] (https://github.com/spring-projects/spring-boot/blob/v1.5.10.RELEASE/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/Http401AuthenticationEntryPoint .java) – CorayThan

0

Özel durumları istisnalara göre yapmak için AuthenticationEntryPoint ürününü genişletmeniz gerekir.

@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 { 
    // 401 
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization Failed : " + accessDeniedException.getMessage()); 
    } 
} 

aşağıda sevdiği SecurityConfig yukarıdaki özel AuthenticationEntryPoint belirtin:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity (prePostEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http.exceptionHandling() 
     .authenticationEntryPoint(new MyAuthenticationEntryPoint()); 
    } 
} 
İlgili konular