2013-02-27 15 views
15

Proteggiamo i nostri servizi REST (per comunicazioni server-server, nessun utente coinvolto) con Spring Security OAuth2. Tuttavia, quando si cerca di accedere a una risorsa protetta in un browser, mostrerà:Personalizza SpringSecurity OAuth 2 Error Output (non autorizzato)

<oauth> 
    <error_description> 
     An Authentication object was not found in the SecurityContext 
    </error_description> 
    <error>unauthorized</error> 
</oauth> 

Vogliamo che questa sia una pagina personalizzata di nostra scelta. C'è un modo?

L'impostazione della pagina di accesso negato non verrà eseguita. Per uno richiede la definizione di una pagina di accesso che non abbiamo in quanto si tratta di una pura comunicazione server-server. Per un altro questo attributo è presumibilmente deprecato dalla primavera 3.0 .. o qualcosa del genere.

In ogni caso .. Debug in modo corretto nella gestione degli errori di OAuth. E ho scoperto che la risposta sembra in qualche modo arricchirsi con le informazioni che vedo nella pagina degli errori. Apparentemente nessun rendering di pagina è stato fatto, quindi sembra che non ci sia una pagina di errore da sostituire ..?!

Almeno vogliamo nascondere il fatto che usiamo OAuth e basta visualizzare un testo "Negato" di base se non possiamo avere una pagina "reale" .. Quindi forse dovrò estendere il gestore di sicurezza di primavera o aggiungi un filtro personalizzato per modificare la risposta ?!

Forse un reindirizzamento alla nostra pagina di errore?

Grazie!

Modifica

per il nostro check configurazione attuale my other SO question here

+0

Sto provando a fare la stessa cosa al momment. Non sai ancora come, se hai una soluzione, per favore condividi. Ho trovato questa discussione sul forum (link sotto), e sembra che abbia qualcosa a che fare con l'utilizzo del gestore di RestTemplate ... http://forum.springsource.org/showthread.php?132846-Securing-REST-with-OAuth2 -Authentication-object-was-not-found-in-the-SecurityContext – rafaelxy

+0

Penso di aver capito ora, il server OAuth non gestirà l'errore e il reindirizzamento, che è una responsabilità dell'applicazione client che tenta di autenticare. Ho ragione? – rafaelxy

+0

Non lo so se questo funzionerà con OAuth ma non farebbe questo il lavoro?

risposta

13

ho dovuto togliere dettaglio OAuth troppo e la mia soluzione era quella di implementare il mio OAuth2ExceptionRenderer

package org.some.nice.code; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.springframework.http.HttpEntity; 
import org.springframework.http.HttpHeaders; 
import org.springframework.http.HttpInputMessage; 
import org.springframework.http.HttpOutputMessage; 
import org.springframework.http.ResponseEntity; 
import org.springframework.http.server.ServerHttpResponse; 
import org.springframework.http.server.ServletServerHttpRequest; 
import org.springframework.http.server.ServletServerHttpResponse; 
import org.springframework.security.oauth2.provider.error.OAuth2ExceptionRenderer; 
import org.springframework.web.context.request.NativeWebRequest; 
import org.springframework.web.context.request.ServletWebRequest; 

public class HeaderOnlyOAuth2ExceptionRenderer implements OAuth2ExceptionRenderer 
{ 
    private final Log logger = LogFactory 
      .getLog(MyOAuth2ExceptionRenderer.class); 

    public void handleHttpEntityResponse(HttpEntity<?> responseEntity, 
      ServletWebRequest webRequest) throws Exception 
    { 
     if (responseEntity == null) 
     { 
      return; 
     } 
     HttpInputMessage inputMessage = createHttpInputMessage(webRequest); 
     HttpOutputMessage outputMessage = createHttpOutputMessage(webRequest); 
     logger.info("filtering headers only..."); 
     if (responseEntity instanceof ResponseEntity 
       && outputMessage instanceof ServerHttpResponse) 
     { 
      ((ServerHttpResponse) outputMessage) 
        .setStatusCode(((ResponseEntity<?>) responseEntity) 
          .getStatusCode()); 
     } 
     HttpHeaders entityHeaders = responseEntity.getHeaders(); 
     if (!entityHeaders.isEmpty()) 
     { 
      outputMessage.getHeaders().putAll(entityHeaders); 
     } 
    } 

    private HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) 
      throws Exception 
    { 
     HttpServletRequest servletRequest = webRequest 
       .getNativeRequest(HttpServletRequest.class); 
     return new ServletServerHttpRequest(servletRequest); 
    } 

    private HttpOutputMessage createHttpOutputMessage(
      NativeWebRequest webRequest) throws Exception 
    { 
     HttpServletResponse servletResponse = (HttpServletResponse) webRequest 
       .getNativeResponse(); 
     return new ServletServerHttpResponse(servletResponse); 
    } 
} 

Poi si dovrà riferimento all'interno del vostro contesto primaverile

 <bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
     <property name="realmName" value="theRealm" /> 
<property name="exceptionRenderer" ref="headerOnlyExceptionRender" /> 
    </bean> 

    <bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
     <property name="realmName" value="theRealm/client" /> 
     <property name="typeName" value="Basic" /> 
<property name="exceptionRenderer" ref="headerOnlyExceptionRender" /> 
    </bean> 



    <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"> 
<property name="exceptionRenderer" ref="headerOnlyExceptionRender" /> 
</bean> 


    <bean id="headerOnlyExceptionRender" class="org.some.nice.code.HeaderOnlyOAuth2ExceptionRenderer"/> 

Spero che aiuti.

+0

Grazie! Quindi è come pensavo .. proverò la tua soluzione al più presto – Pete

Problemi correlati