2013-02-27 6 views
15

Zabezpieczamy nasze usługi REST (dla komunikacji serwer-serwer, bez udziału użytkownika) z Spring Security OAuth2. Jednak, gdy ktoś próbuje uzyskać dostęp do chronionego zasobu w przeglądarce, to pokaże:Dostosuj SpringSecurity OAuth 2 Wyjście błędu (nieautoryzowane)

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

Chcemy to za zwyczaj strona naszego własnego wyboru. Czy istnieje sposób?

Ustawienie strony zabronionej przez dostęp zabronione. Po pierwsze wymaga zdefiniowania strony logowania, której nie mamy, ponieważ jest to czysta komunikacja między serwerami. W przypadku innego tego atrybutu jest rzekomo przestarzałe od wiosny 3.0 .. lub coś.

W każdym razie ... Debugowałem moją drogę do obsługi błędów OAuth. Okazało się, że odpowiedź w jakiś sposób wzbogaca się o informacje, które widzę na stronie błędu. Wygląda na to, że w ogóle nie jest wykonywane renderowanie strony, więc wygląda na to, że nie ma strony błędu do zastąpienia ...?!

Przynajmniej chcemy ukryć fakt, że używamy OAuth i wyświetlać zwykły tekst "Odmowa", jeśli nie możemy mieć "prawdziwej" strony. Więc może będę musiał rozszerzyć obsługę zabezpieczeń wiosennych lub dodać niestandardowy filtr, aby zmodyfikować odpowiedź ?!

Może przekierowanie do naszej strony błędów?

Dzięki!

Edit

Dla naszego obecnego Sprawdź konfigurację my other SO question here

+0

Próbuję zrobić to samo w momment. Nie wiesz, jak jeszcze, jeśli masz rozwiązanie, udostępnij. Znalazłem tę (link poniżej) dyskusję na forum i wydaje się, że ma to coś wspólnego z używaniem programu obsługi RestTemplate ... http://forum.springsource.org/showthread.php?132846-Securing-REST-with-OAuth2 -Authentication-object-was-not-found-in-the-SecurityContext – rafaelxy

+0

Myślę, że teraz zrozumiałem, że serwer OAuth nie będzie obsługiwał błędów i przekierowań, co jest obowiązkiem aplikacji klienta próbującej uwierzytelnić. Czy mam rację? – rafaelxy

+0

Nie wiem teraz, czy to zadziała z OAuth, ale nie wykona tego zadania?

Odpowiedz

13

musiałem usunąć szczegół OAuth też i moje rozwiązanie było realizować własne 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); 
    } 
} 

Potem trzeba będzie podaj to w kontekście twojej wiosny

 <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"/> 

Mam nadzieję, że to pomaga.

+0

Dzięki! Tak jak myślałem ... wypróbuje twoje rozwiązanie jak najszybciej – Pete

Powiązane problemy