SpringBoot Security的自定義異常

access_denied 方面異常

原異常

{
    "error": "access_denied",
    "error_description": "不允許訪問"
}

現異常

{
    "success": false,
    "error": "access_denied",
    "status": 403,
    "message": "不允許訪問",
    "path": "/user/get1",
    "timestamp": 1592378892768
}

實現

public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        // access_denied 方面異常
        OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler = new OAuth2AccessDeniedHandler();
        oAuth2AccessDeniedHandler.setExceptionTranslator(new CustomWebResponseExceptionTranslator());
        resources.accessDeniedHandler(oAuth2AccessDeniedHandler);
    }
}

Invalid access token 方面異常

原異常

{
    "error": "invalid_token",
    "error_description": "Invalid access token: 4eb58ecf-e66de-4155-9477-64a1c9805cc8"
}

現異常

{
    "success": false,
    "error": "invalid_token",
    "status": 401,
    "message": "Invalid access token: 8cd45925dbf6-4502-bd13-8101bc6e1d4b",
    "path": "/user/get1",
    "timestamp": 1592378949452
}

實現

public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
         // Invalid access token 方面異常
        OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        authenticationEntryPoint.setExceptionTranslator(new CustomWebResponseExceptionTranslator());
        resources.authenticationEntryPoint(authenticationEntryPoint);
    }
}

Bad credentials 方面異常(登陸出錯)

原異常

{
    "error": "invalid_grant",
    "error_description": "用戶名或密碼錯誤"
}

現異常

{
    "success": false,
    "error": "invalid_grant",
    "status": 400,
    "message": "用戶名或密碼錯誤",
    "path": "/oauth/token",
    "timestamp": 1592384576019
}

實現

public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

     @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.userDetailsService(detailsService)
                .tokenStore(memoryTokenStore())
                .exceptionTranslator(new CustomWebResponseExceptionTranslator())
                .authenticationManager(authenticationManager)
                //接收GET和POST
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }
}

其他類

@Getter
@JsonSerialize(using = CustomOauthExceptionSerializer.class)
public class CustomOauthException extends OAuth2Exception {

    private String oAuth2ErrorCode;

    private int httpErrorCode;

    public CustomOauthException(String msg, String oAuth2ErrorCode, int httpErrorCode) {
        super(msg);
        this.oAuth2ErrorCode = oAuth2ErrorCode;
        this.httpErrorCode = httpErrorCode;
    }
}
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
    private static final long serialVersionUID = 2652127645704345563L;

    public CustomOauthExceptionSerializer() {
        super(CustomOauthException.class);
    }

    @Override
    public void serialize(CustomOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        gen.writeObjectField("success",false);
        gen.writeObjectField("error",value.getOAuth2ErrorCode());
        gen.writeObjectField("status", value.getHttpErrorCode());
        gen.writeObjectField("message", value.getMessage());
        gen.writeObjectField("path", request.getServletPath());
        gen.writeObjectField("timestamp", (new Date()).getTime());
        if (value.getAdditionalInformation()!=null) {
            for (Map.Entry<String, String> entry : value.getAdditionalInformation().entrySet()) {
                String key = entry.getKey();
                String add = entry.getValue();
                gen.writeObjectField(key, add);
            }
        }
        gen.writeEndObject();
    }
}

public class CustomWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {

    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
        ResponseEntity<OAuth2Exception> translate = super.translate(e);
        OAuth2Exception body = translate.getBody();

        CustomOauthException customOauthException = new CustomOauthException(body.getMessage(),body.getOAuth2ErrorCode(),body.getHttpErrorCode());
        ResponseEntity<OAuth2Exception> response = new ResponseEntity<>(customOauthException, translate.getHeaders(),
                translate.getStatusCode());
        return response;
    }

}

補充

{
    "error": "invalid_client",
    "error_description": "Bad client credentials"
}

如果client_secret錯誤依然還是報錯,如上內容,針對這個異常需要在如下方法中的addTokenEndpointAuthenticationFilter添加過濾器處理

  @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
      oauthServer
                // 開啓/oauth/token_key驗證端口無權限訪問
                .tokenKeyAccess("permitAll()")
                // 開啓/oauth/check_token驗證端口認證權限訪問
                .checkTokenAccess("isAuthenticated()")
                .addTokenEndpointAuthenticationFilter(null)
                .allowFormAuthenticationForClients();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章