【问题标题】:Getting error details from JHipster UAA microservice through gateway通过网关从 JHipster UAA 微服务获取错误详细信息
【发布时间】:2018-10-04 14:22:04
【问题描述】:

上下文:我们的应用使用 JHipster 生成的网关和 UAA 服务(微服务架构)。 在尝试失败次数过多后,我们正在实施阻止用户帐户。

当被阻止的用户尝试登录时,UAA 服务会返回 400 Bad Request,并在 error_description 字段中使用自定义 i18n 代码,前端可以使用该代码来显示正确的用户错误:

{
  "error" : "invalid_grant",
  "error_description" : "error.login.locked"
}

到目前为止一切顺利。

通过网关发出登录请求时会出现问题,因为答案是:

{
  "type" : "http://www.jhipster.tech/problem/problem-with-message",
  "title" : "Internal Server Error",
  "status" : 500,
  "detail" : "400 Bad Request",
  "path" : "/auth/login",
  "message" : "error.http.500"
}

这里有 2 个问题

  1. HTTP状态为500,同样是密码错误导致登录失败... 这是生成网关的正常预期行为吗?

  2. 前端必需的 errorerror_description 字段在通过网关时丢失了。

有没有比编辑网关authenticate 方法更好的方法,检查HttpClientErrorExceptionfor 并解析OAuth2Exception 以获取详细信息,引发自定义异常,然后由Exceptiontranslator 处理以保存所需的字段?这似乎有点多,只是为了能够保留服务发送的数据。

【问题讨论】:

  • 你找到解决办法了吗?

标签: spring jhipster microservices


【解决方案1】:

这是我最终使用的 - 可能不是正确的最佳解决方案,但它可以按我的需要工作:

OAuth2AuthenticationService 中,我捕获了异常(这样它就不会冒泡为 500 内部错误)

 public ResponseEntity<OAuth2AccessToken> authenticate(HttpServletRequest request, HttpServletResponse response,
                                                      Map<String, String> params) {
    try {
        [...]
        OAuth2AccessToken accessToken = authorizationClient.sendPasswordGrant(username, password);
        [...]
        return ResponseEntity.ok(accessToken);
    } catch (HttpClientErrorException ex) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            // Throw the original exception from auth-service to keep its message (i18n code used by the frontend in my case)
            throw mapper.readValue(ex.getResponseBodyAsString(), OAuth2Exception.class);
        } catch (IOException e) {
            // If it's not a OAuth2Exception, let the error get thrown
            throw ex;
        }
    } catch (Exception ex) {
        // If it's not a OAuth2Exception, let the error get thrown
        throw ex;
    }

AuthResource.authenticate() 方法中,我捕获了这些 OAuth2Exception,将它们包装在自定义的 AuthenticationFailureException 类中,并让 ExceptionTranslator 将正确的对象返回到前端(注意 BadRequest 状态和消息负载):

@ExceptionHandler(AuthenticationFailureException.class)
public ResponseEntity<Problem> handleBadRequestAlertException(AuthenticationFailureException ex, NativeWebRequest request) {
    Problem problem = Problem.builder()
        .withStatus(BAD_REQUEST)
        .with("message", ex.getMessage())
        .build();
    return create(ex, problem, request);
}

【讨论】:

  • @AlexandreCassagne :希望这可以帮助你
猜你喜欢
  • 1970-01-01
  • 2016-12-20
  • 2016-11-25
  • 2021-03-23
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多