2015-03-30 21 views
9

Có cách nào để thêm Trình xử lý thành công khi đăng nhập bằng spring-oauth2 không?Trình xử lý thành công đăng nhập spring-oauth2

Tôi đã thử sử dụng Bộ lọc xác thực cơ bản nhưng bộ lọc chỉ lọc thông tin đăng nhập của khách hàng chứ không phải bằng chứng xác thực người dùng.

Hoặc tôi có cần tạo trình quản lý xác thực người dùng tùy chỉnh không?

TIA

Trả lời

0

Chúng tôi xây dựng một nhà quản lý xác thực tùy chỉnh mà chúng tôi có dây vào OAuth2AuthenticationProcessingFilter để thực hiện điều này. Phương thức xác thực của người quản lý có thể giải nén OAuth2Authentication và OAuth2AuthenticationDetails khỏi hiệu trưởng xác thực.

<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

Giải pháp này sẽ hoạt động cho lưu lượng mật khẩu và cho những người khác mà tôi không chắc chắn. Bạn có thể thêm bộ lọc tùy chỉnh ở vị trí "before = BASIC_AUTH_FILTER" trong thẻ http có cấu hình oauth-server, và bạn có thể đạt được bằng cách phân tích cú pháp "oauth/token" để tạo ByteArrayResponseWrapper để nhận phản hồi, Tại đây tôi đang sử dụng lớp TeeOutputStream từ "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(); 
    } 
} 

và tôi đã tạo ra vắt thẻ để tách mã chiết xuất 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; 
} 

} 

sau khi tạo doFilter lọc ghi đè của bạn như này

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) { 
} 

trong khi tạo mã thông báo cấp phép lọc bộ lọcServices. tại onSuccessfulClientAuthentication, onFailClientAuthentication, onSuccessfulUserAuthentication và onFailureUserAuthentication sẽ được gọi theo ý muốn xác thực của bạn

để biết thêm bạn có thể tham khảo mã này vào github

được sửa đổi:

Đoạn trên hoạt động tốt khi bạn có mặc định token response và nó chỉ sử dụng ServletResponseWrapper và giải nén. Nhưng vẫn có vẻ như dễ bị tổn thương để bạn có thể biết được thành công xác thực người dùng bằng cách thông qua org.springframework.security.oauth2.provider.token.TokenEnhancer lớp

Làm theo chi tiết answer này để biết chi tiết.

+0

Cảm ơn. Đó là ngoài tôi lý do tại sao các tác giả của oauth2 mùa xuân đã phá vỡ thiết kế đã được chứng minh với thành công đơn giản/xử lý thất bại đã làm việc rất tốt trong quá khứ. –

Các vấn đề liên quan