簡體   English   中英

Spring Oauth2 - 自定義異常處理程序

[英]Spring Oauth2 - custom exception handler

在基於 Spring Security Oauth2 的身份驗證中,當客戶端發送需要刷新的訪問令牌時,DefaultTokenServices 類會拋出 InvalidTokenException(參見第 235 行):

https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java

發生這種情況時的輸出類似於:

{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"
}

我想更改此輸出,但我迷路了。 其他一些答案建議設立一個自定義exceptionRenderer但這並沒有在這兩個案例,我的自定義異常渲染器不會被調用。

還有一種叫做異常翻譯器的東西,但它們在任何情況下都沒有被調用。

我的彈簧配置的一部分:

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


<bean id="oauthAuthenticationEntryPoint"
      class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
      <property name="exceptionRenderer" ref="myExceptionRenderer" />
      <property name="exceptionTranslator" ref="listyOauthExceptionTranslator" />
</bean>

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

<bean id="myExceptionRenderer" class="com.example.exceptions.MyOauth2ExceptionRenderer" />

<bean id="myExceptionTranslator" class="com.example.exceptions.MyOauth2ExceptionTranslator" />

異常渲染器:

public class MyExceptionRenderer implements OAuth2ExceptionRenderer {

@Override
public void handleHttpEntityResponse(HttpEntity<?> responseEntity, ServletWebRequest webRequest) throws Exception {
    System.out.println("Thrown exception");
}

}

我還添加了一個自定義異常映射器,它應該獲取所有異常,但是因為我假設它是另一個 servlet,所以在這種情況下它真的不起作用?

@Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {

@Override 
public Response toResponse(Throwable ex) {
    System.out.println("MAPPING EXCEPTION");
    return Response.status(200).entity().build();
}
}

我可以捕獲AuthenticationException 的情況,但不能捕獲任何InvalidTokenExceptions

對此有任何幫助嗎? Spring實際上在哪里捕獲這個 InvalidTokenException 以及如何設置它以便我可以提供自定義輸出?

InvalidTokenException 擴展了ClientAuthenticationException 因此,您可以通過擴展ClientAuthenticationException創建自己的異常並拋出它而不是InvalidTokenException

public class CustomException extends ClientAuthenticationException {

    public CustomException(String msg, Throwable t) {
        super(msg, t);
    }

    public CustomException(String msg) {
        super(msg);
    }
    @Override
    public String getOAuth2ErrorCode() {
        return "my_custom_exception";
    }
}

喜歡

throw new CustomException("Invalid access token: " + accessTokenValue);

在 InvalidTokenException 拋出的錯誤中

 {"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"}

invalid_token由 InvalidTokenException 和Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9getOAuth2ErrorCode()方法返回Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9是您在拋出異常時給出的消息。

如果你扔

 throw new CustomException("This is my custom exception");

錯誤將顯示為

{"error":"my_custom_exception","error_description":"This is my custom exception"}

my_custom_exception是來自getOAuth2ErrorCode()CustomException

答案並沒有真正提供自定義實現,自定義響應將是代碼中的一個點,我可以在其中訪問默認響應,並且可以發送 POJO 代替它,例如,如果您想將error_description更改為error_info或其他任何內容,或者您可能希望向響應添加更多變量。 解決方案確實存在,但我認為至少可以說實現起來很痛苦,因為我從這里復制它:

這個問題已經解決了。 請按照以下解決方法操作:

  1. OAuth2Exception擴展到一個新類,例如 CustomOAuth2Exception。 在自定義類中,添加一些特定的屬性。
  2. 自定義DefaultWebResponseExceptionTranslator並在AuthorizationServerConfiguration注冊自定義轉換器。
  3. 自定義兩個在OAuth2Exception注釋的 jackson 序列化OAuth2Exception並使用兩個自定義序列化程序注釋您的CustomOAuth2Exception
  4. 使用ObjectMapper用自定義序列化器覆蓋初始序列化器。

用於覆蓋

{"error":"invalid_token","error_description":"Invalid access token: a0cb5ab9-7281-46bd-a9a2-796a04a906c9"
}

您需要繼承 ResourceServerConfigurerAdapter 並覆蓋 public void configure(final ResourceServerSecurityConfigurer config)

示例代碼

package com.org.security;

import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.stereotype.Component;


@Component
public class CustomWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {

    /**
     * Modify OAuth2.0 Error Response
     * @param e
     * @return ResponseEntity<OAuth2Exception>
     * @throws Exception
     */

    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
        ResponseEntity responseEntity = super.translate(e);
        OAuth2Exception auth2Exception = (OAuth2Exception)responseEntity.getBody();
        if (auth2Exception != null) {
            auth2Exception.addAdditionalInformation("data", null);
            auth2Exception.addAdditionalInformation("message", auth2Exception.getMessage());
            auth2Exception.addAdditionalInformation("statusCode", String.valueOf(auth2Exception.getHttpErrorCode()));
        }
        return new ResponseEntity<OAuth2Exception>(auth2Exception, responseEntity.getHeaders(), responseEntity.getStatusCode());
    }
}





package com.org.security;

import com.org.exception.CustomAuthExceptionEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;


@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private ResourceServerTokenServices tokenServices;

    @Autowired
    private WebResponseExceptionTranslator oauth2ResponseExceptionTranslator;

    @Override
    public void configure(final ResourceServerSecurityConfigurer config) {
        OAuth2AccessDeniedHandler auth2AccessDeniedHandler = new OAuth2AccessDeniedHandler();
        auth2AccessDeniedHandler.setExceptionTranslator(oauth2ResponseExceptionTranslator);
        OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        authenticationEntryPoint.setExceptionTranslator(oauth2ResponseExceptionTranslator);
        config.tokenServices(tokenServices).accessDeniedHandler(auth2AccessDeniedHandler).authenticationEntryPoint(authenticationEntryPoint);
    }

}

這是我對自定義 AuthorizationServer 和 ResourceServer 異常的解決方案。 可能會有所幫助。

Spring Security Oauth - OAuth2Exceptions 的自定義格式

暫無
暫無

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

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