定制dropwizard初始未经授权的消息json格式的Java



我们正在使用dropwizard 0.9。X中,我们编写了自定义类,用于在检索数据之前验证用户输入的令牌。我想自定义初始未经授权的消息"需要凭据访问此资源。"JSON格式,我想显示如下。

{
  "code": 401,
  "message": "HTTP 401 Unauthorized, Credentials are required to access this resource."
}

我已经编写了AbstractStatusType来实现StatusType,并且我能够在用户输入无效令牌或过期令牌时打印上述格式消息。示例承载03cb9ebe-1c66-4d08-b9a4-afe69989ef21

但是当用户只输入"持有者"或只输入令牌"03cb9ebe-1c66-4d08-b9a4-afe69989ef21"时,我仍然得到纯文本响应体"访问此资源需要凭据"。

你能帮我把上面的文本格式消息定制成上面的JSON格式吗?

下面是设置响应"凭据需要访问此资源"的自定义代码,它内部使用dropwizard OAuthCredentialAuthFilter类

public AuthDynamicFeature getAuthFilter(CachingAuthenticator<String, AuthenticatedPrincipal> cachingAuthenticator) {
    OAuthCredentialAuthFilter<AuthenticatedPrincipal> authFilter = new OAuthCredentialAuthFilter.Builder<AuthenticatedPrincipal>()
            .setAuthenticator(cachingAuthenticator)
            .setAuthorizer(new OAuthAuthorizer())
            .setRealm(REALM)
            .setPrefix(PREFIX)
            .buildAuthFilter();
    return new AuthDynamicFeature(authFilter);
}

提前感谢您的帮助!

@Arthur,

我已经实现了UnauthorizedHandler与JsonUnauthorizedHandler如下,它工作得很好。

public class JsonUnauthorizedHandler implements UnauthorizedHandler {
    private static final String CHALLENGE_FORMAT = "%s realm="%s"";
    @Override
    public Response buildResponse(String prefix, String realm) {
        // Create an HTTP 401 Unauthorized response with a JSON payload of a
        // human readable error
        return Response.status(Response.Status.UNAUTHORIZED)
                .header(HttpHeaders.WWW_AUTHENTICATE,
                        String.format(CHALLENGE_FORMAT, prefix, realm))
                .type(MediaType.APPLICATION_JSON_TYPE)
                .entity(ImmutableMap.of("code","401",
                        "message",
                        "HTTP 401 Unauthorized, Credentials are required to access this resource."))
                .build();
    }
}

然后我设置如下getAuthFilter。

public AuthDynamicFeature getAuthFilter(CachingAuthenticator<String, AuthenticatedPrincipal> cachingAuthenticator) {
    OAuthCredentialAuthFilter<AuthenticatedPrincipal> authFilter = new OAuthCredentialAuthFilter.Builder<AuthenticatedPrincipal>()
            .setAuthenticator(cachingAuthenticator)
            .setAuthorizer(new OAuthAuthorizer())
            .setRealm(REALM)
            .setPrefix(PREFIX)
            .setUnauthorizedHandler(new JsonUnauthorizedHandler())
            .buildAuthFilter();
    return new AuthDynamicFeature(authFilter);
}

以下是我在swagger发布上述更改后收到的响应。

{
  "code": 401,
  "message": "HTTP 401 Unauthorized, Credentials are required to access this resource."
}

谢谢你的建议。

谢谢破布

为此,您需要在DW上设置UnauthorizedHandler:

public AuthDynamicFeature getAuthFilter(CachingAuthenticator<String, AuthenticatedPrincipal> cachingAuthenticator) {
    OAuthCredentialAuthFilter<AuthenticatedPrincipal> authFilter = new OAuthCredentialAuthFilter.Builder<AuthenticatedPrincipal>()
            .setAuthenticator(cachingAuthenticator)
            .setAuthorizer(new OAuthAuthorizer())
            .setRealm(REALM)
            .setPrefix(PREFIX)
            .setUnauthorizedHandler(new MyUnauthorizedHandler())
            .buildAuthFilter();
    return new AuthDynamicFeature(authFilter);
}

setUnauthorizedHandler方法设置此属性。

然后您可以通过实现该接口来定制响应:

public static class MyUnauthorizedHandler implements UnauthorizedHandler {
        @Override
        public Response buildResponse(String prefix, String realm) {
            return Response.status(Status.UNAUTHORIZED).entity("").build();
        }
    }

希望有帮助,

阿图尔

最新更新