簡體   English   中英

spring-oauth2登錄成功處理程序

[英]spring-oauth2 login success handler

有沒有一種方法可以使用spring-oauth2添加登錄成功處理程序?

我嘗試使用基本身份驗證篩選器,但它僅篩選客戶端憑據而不篩選用戶憑據。

還是我需要創建一個自定義用戶身份驗證管理器?

TIA

此解決方案適用於密碼流,但我不確定其他解決方案。 您可以在oauth-server配置中的http標記中的“ before = BASIC_AUTH_FILTER”位置添加自定義過濾器,並且可以通過解析“ oauth / token”的響應來實現,因此創建ByteArrayResponseWrapper以獲得響應,這里我使用的是TeeOutputStream “ 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();
    }
}

並且我創建了令牌提取器來分離提取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;
 }

}

在創建過濾器后,像這樣覆蓋doFilter

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

在創建過濾器實例時注入tokenServices。 現在將根據您的身份驗證調用onSuccessfulClientAuthentication,onFailClientAuthentication,onSuccessfulUserAuthentication和onFailureUserAuthentication

有關更多信息,您可以在github上引用此代碼

編輯:

當您具有默認令牌響應並且僅使用ServletResponseWrapper和提取時,上述代碼片段可以正常工作。 但它似乎仍然很脆弱,因此您可以通過org.springframework.security.oauth2.provider.token.TokenEnhancer類來了解用戶身份驗證成功

遵循此答案以獲取詳細信息。

我們構建了一個自定義身份驗證管理器,將其連接到OAuth2AuthenticationProcessingFilter即可完成此操作。 管理員的authenticate方法能夠從身份驗證主體中解壓縮OAuth2Authentication和OAuth2AuthenticationDetails。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM