如何包装OAuth2异常? [英] How to wrap an OAuth2 exception?

查看:277
本文介绍了如何包装OAuth2异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个使用 Spring OAuth2 的其他API。用户通过身份验证后,所有JSON响应都采用以下格式:

We have a rest API that uses Spring OAuth2. After the user is authenticated, all the JSON responses are in the following format:

{"code" : 12345, "data" : "..." }

但是,身份验证失败的JSON响应与上述格式不符,因为这是由Spring处理的。

But the JSON response for authentication failures is not inline with the above format, as that is handled by Spring.

例如,如果凭据不正确,客户端将获得带有JSON响应的
HTTP状态代码400,如下所示:

For example in case of incorrect credentials, the clients get HTTP status code 400 with JSON response as follows:

{"error": "invalid_grant", "error_description": "Bad credentials" }

如果用户帐户被锁定,客户端将获得带有JSON响应的HTTP状态代码400,如下所示

In case the user account is locked, the clients get HTTP status code 400 with JSON response as follows

{"error":"invalid_grant","error_description":"User account is locked"}

所有这一切都是因为Spring TokenEndpoint.handleException()正在处理与/ oauth / token相关的异常

All of this is because Spring TokenEndpoint.handleException() is handling the exceptions associated with /oauth/token

我想更改OAuth2的JSON响应没有遵循第一种格式。

I would like to change the JSON response for OAuth2 failures to follow the first format.

这是我迄今为止尝试过的但没有成功:

This is what I have tried so far with no success:


  1. 使用具有最高优先级顺序的ControllerAdvice&使用@ExceptionHandler,如此处

  2. 按照此处所述实施OAuth2ExceptionRenderer

  3. 实现ExceptionMapper

  4. 添加了一个带有扩展StdSerializer的新ObjectMapper。虽然我的objectmapper已初始化,但它不用于序列化异常。也许是因为Spring直接调用MappingJackson2HttpMessageConverter而且我的应用程序中似乎有这个类的几个实例。

  1. Use ControllerAdvice with highest precendence order & use @ExceptionHandler as described here
  2. implementing OAuth2ExceptionRenderer as described here
  3. implement ExceptionMapper
  4. added a new ObjectMapper with extending StdSerializer. Although my objectmapper is initialized it is not being used for serializing the exceptions. Maybe because Spring is calling MappingJackson2HttpMessageConverter directly and there seems to be several instances of this class in my app.

任何帮助上述方法或新方法将受到高度赞赏。

Any help in any of the above approaches or a new one would be highly appreciated.

我还没试过这个方法,因为我无法更改现有客户端的上下文路径。

I haven't tried this approach as I cannot change the contextpath for the existing clients.

推荐答案

我遇到了完全相同的问题并最终解决了问题。
我使用自定义的ExceptionHandlerExceptionResolver类作为解析器,它覆盖了方法 getExceptionHandler ,如下面的代码所示,然后再次使用具有最高优先级顺序的@ControllerAdvice,最后它可以工作。

I faced exact same issue and workout a solution eventually. I use a customized ExceptionHandlerExceptionResolver class as resolver which overwrited method getExceptionHandler as show in below code, and then use @ControllerAdvice with highest precendence order again, finally it works.

public class MyExceptionHandlerExceptionResolver extends ExceptionHandlerExceptionResolver {
private Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = null;

@Override
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
    Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null);
    List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
    if (exceptionHandlerAdviceCache==null){
        exceptionHandlerAdviceCache = new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>();
        for (ControllerAdviceBean adviceBean:adviceBeans){
            ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(adviceBean.getBeanType());
            exceptionHandlerAdviceCache.put(adviceBean, resolver);
        }
    }
    for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
        if (entry.getKey().isApplicableToBeanType(handlerType)) {
            ExceptionHandlerMethodResolver resolver = entry.getValue();
            Method method = resolver.resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(entry.getKey().resolveBean(), method);
            }
        }
    }
    return null;
}
}

在configure中使用MyExceptionHandlerExceptionResolver类

use MyExceptionHandlerExceptionResolver class in configure

@EnableWebMvc
@Configuration
public class WebMVCConfiguration extends WebMvcConfigurationSupport {
@Bean
public ExceptionHandlerExceptionResolver handlerExceptionResolver() {
    MyExceptionHandlerExceptionResolver exceptionResolver = new MyExceptionHandlerExceptionResolver();
    exceptionResolver.setOrder(0);
    exceptionResolver.setMessageConverters(messageConverters());
    return exceptionResolver;
}

private MappingJackson2HttpMessageConverter jsonHttpMessageConverter() {
    return new MappingJackson2HttpMessageConverter();
}

private List<HttpMessageConverter<?>> messageConverters() {
    List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
    messageConverters.add(jsonHttpMessageConverter());
    return messageConverters;
}
}

这篇关于如何包装OAuth2异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆