上下文:我们的应用程序使用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个问题:
HTTP状态为500.由于密码错误导致登录失败,情况也是如此... 这是生成的网关的正常预期行为吗?
通过网关丢失了前端所需的error
和error_description
字段。
有没有比编辑网关authenticate
方法更好的方法,检查HttpClientErrorExceptionfor
并解析OAuth2Exception
以获取详细信息,引发自定义异常,然后由Exceptiontranslator
为了保存所需的字段?这似乎有点多,只是为了能够保存服务发送的数据。
答案 0 :(得分:0)
这是我最终使用的-可能不是适当的最佳解决方案,但它可以按我的需要工作:
在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);
}