2015-03-30 33 views
9

Czy istnieje sposób na dodanie narzędzia do logowania się przy użyciu funkcji spring-oauth2?pomocnik do logowania spring-oauth2

Próbowałem użyć podstawowego filtru uwierzytelniającego, ale filtruje on tylko poświadczenia klienta, a nie poświadczenia użytkownika.

Czy muszę utworzyć niestandardowego menedżera autoryzacji użytkownika?

TIA

Odpowiedz

0

Zbudowaliśmy Authentication Manager zwyczaj które przewodowe do OAuth2AuthenticationProcessingFilter, aby to zrobić. Metoda uwierzytelniania menedżera umożliwia rozpakowanie uwierzytelnienia OAuth2Authentication i OAuth2AuthenticationDetails od głównego podmiotu uwierzytelniającego.

<bean id="oAuth2AuthenticationManager" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager"> 
    <property name="resourceId" value="XXX-api"/> 
    <property name="tokenServices" ref="tokenServices"/> 
</bean> 

<bean id="resourceServerFilter" 
     class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter"> 
    <property name="authenticationManager" ref="oAuth2AuthenticationManager"/> 
    <property name="tokenExtractor"> 
     <bean class="com.xxx.oauth.BearerTokenExtractor"/> 
    </property> 
</bean> 
5

To rozwiązanie będzie działało na rzecz przepływu haseł, a dla innych nie jestem pewien. Możesz dodać swój filtr niestandardowy w pozycji "before = BASIC_AUTH_FILTER" w znaczniku http, który znajduje się w konfiguracji serwera auauth, i możesz to osiągnąć, analizując odpowiedź "oauth/token", a następnie utwórz ByteArrayResponseWrapper, aby uzyskać odpowiedź, Tutaj używam klasy TeeOutputStream z "org.apache.commons commons-IO",

private class ByteArrayResponseWrapper extends HttpServletResponseWrapper { 

    public ByteArrayResponseWrapper(ServletResponse response) { 
     super((HttpServletResponse) response); 
    } 

    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 

    @Override 
    public ServletOutputStream getOutputStream() throws IOException { 
     return new DelegatingServletOutputStream(new TeeOutputStream(
       super.getOutputStream(), byteArrayOutputStream)); 
    } 

    public byte[] getByteArray() { 
     return this.byteArrayOutputStream.toByteArray(); 
    } 
} 

i ja stworzyliśmy tokena ściągacza oddzielić kod wydobycia access_token

public class OAuth2AccessTokenExtractor implements 
    OAuth2AccessTokenExtractor { 

private ObjectMapper mapper = new ObjectMapper(); 

public String getAccessTokenValue(byte[] response) { 
    try { 
     return mapper.readValue(response, OAuth2AccessToken.class) 
       .getValue(); 
    } catch (JsonParseException e) { 
     e.printStackTrace(); 
    } catch (JsonMappingException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

} 

po utworzyć filtr nadpisywania doFilter jak to

private DefaultTokenServices tokenServices; 

private OAuth2AccessTokenExtractor tokenExtractor; 

@Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 

    // create wrapper to read response body 
    ByteArrayResponseWrapper responseWraper = new ByteArrayResponseWrapper(
      response); 

    // led them go 
    chain.doFilter(request, responseWraper); 

    // get ClientAuthentication 
    Authentication clientAuthentication = SecurityContextHolder 
      .getContext().getAuthentication(); 

    // is authenticated or not to proceed 
    if (clientAuthentication != null 
      && clientAuthentication.isAuthenticated()) { 

     // callBack client authenticated successfully 
     onSuccessfulClientAuthentication(request, response, 
       clientAuthentication); 

     // check response status is success of failure 
     if (responseWraper.getStatus() == 200) { 

      // extract accessToken from response 
      String token = tokenExtractor 
        .getAccessTokenValue(responseWraper.getByteArray()); 

      if (token != null && !token.isEmpty()) { 

       // load authentication from token 
       OAuth2Authentication oAuth2Authentication = this.tokenServices 
         .loadAuthentication(token); 
       OAuth2AccessToken actualAccessToken = this.tokenServices 
         .getAccessToken(oAuth2Authentication); 

       // callBack user authenticated successfully 
       onSuccessfulUserAuthentication(request, response, 
         clientAuthentication, oAuth2Authentication, 
         actualAccessToken); 
      } else { 
       log.error("access token is empty from extractor"); 
      } 
     } else { 
      // callBack user authenticated failure 
      onFailureUserAuthentication(request, response, 
        clientAuthentication, request.getParameter("username")); 
     } 
    } else { 
     // callBack client authenticated failure 
     onFailClientAuthentication(request, response, 
       request.getParameter(OAuth2Utils.CLIENT_ID)); 
    } 
} 

protected void onSuccessfulClientAuthentication(ServletRequest request, 
     ServletResponse response, Authentication authentication) { 
} 

protected void onFailClientAuthentication(ServletRequest request, 
     ServletResponse response, String clientId) { 
} 

protected void onSuccessfulUserAuthentication(ServletRequest request, 
     ServletResponse response, Authentication clientAuthentication, 
     OAuth2Authentication userOAuth2Authentication, 
     OAuth2AccessToken token) { 
} 

protected void onFailureUserAuthentication(ServletRequest request, 
     ServletResponse response, Authentication clientAuthentication, 
     String username) { 
} 

podczas tworzenia instancji filtru wstrzyknij tokenServices. teraz onSuccessfulClientAuthentication, onFailClientAuthentication, onSuccessfulUserAuthentication i onFailureUserAuthentication będzie nazywany w zależności uwierzytelniania

dłużej można odwołać ten kod na github

edycja:

Powyższy fragment działa dobrze, gdy masz domyślne token response i po prostu używa ServletResponseWrapper i wyodrębniania. Ale nadal wygląda na podatną na uszkodzenia, dzięki czemu można poznać sukces uwierzytelnienia użytkownika poprzez org.springframework.security.oauth2.provider.token.TokenEnhancer klasa

Aby uzyskać szczegółowe informacje, należy postępować zgodnie z tym answer.

+0

Dzięki. To jest ponade mnie, dlaczego autorzy wiosną oauth2 złamali sprawdzony projekt z prostymi narzędziami do sukcesów/niepowodzeń, które sprawdziły się tak dobrze w przeszłości. –