Restlet 2.3覆盖WWW-Authenticate标题

时间:2015-10-08 15:40:28

标签: java authentication restlet restlet-2.3.1

Restlet 2.3 中,我使用ChallengeAuthenticatorChallengeScheme.HTTP_BASIC来保护应用程序资源。当服务器收到一组错误的凭据时,服务器会正​​确返回401 Unauthorized响应。同样正确的是它添加了以下标题:

WWW-Authenticate → Basic realm="My security Realm"

问题是当响应返回到浏览器而不是服务器时(如AngularJS应用程序GUI的情况),浏览器本身解释401响应并启动“需要身份验证”和#39;模态的。

enter image description here

我想要尝试和实现的是阅读请求标头(轻松完成),如果X-Requested-With: XMLHttpRequest标头存在,我想要取消{&#39}中的WWW-Authenticate标头。 401'响应。

目前WWW-Authenticate标头是自动设置的,所以我的问题是如何覆盖设置的默认标头并手动处理?

2 个答案:

答案 0 :(得分:2)

在您的情况下,您应该使用过滤器从响应中删除标题WWW-Authenticate。此标头对应于响应中的质询请求。

以下是过滤器的内容:

public class SecurityPostProcessingFilter extends Filter {
    public SecurityPostProcessingFilter(
              Context context, Restlet next) {
        super(context, next);
    }

    @Override
    protected void afterHandle(Request request, Response response) {
        String requestedWith
           = request.getHeaders().getFirstValue("X-Requested-With");
        if ("XMLHttpRequest".equals(requestedWith)) {
            response.getChallengeRequests().clear();
        }
    }
}

您需要在Restlet应用程序的createInboundRoot方法中添加它,如下所述

public class RestletApplication extends Application {
    (...)

    @Override
    public Restlet createInboundRoot() {
        Router router = new Router(getContext());
        (...)

        ChallengeAuthenticator guard = new ChallengeAuthenticator(
                null, ChallengeScheme.HTTP_BASIC, "testRealm");
        (...)
        guard.setNext(router);

        Filter filter = new SecurityPostProcessingFilter(
             getContext(), guard);

        return filter;
    }
}

当标头WWW-Authenticate的值等于请求中的X-Requested-From时,这将从响应中删除标头XMLHttpRequest

仅供参考,Restlet网站上有一个页面,描述HTTP标头和Restlet API之间的映射:http://restlet.com/technical-resources/restlet-framework/guide/2.2/core/http-headers-mapping

希望它可以帮到你, 亨利

答案 1 :(得分:0)

另一种方法是覆盖ChallengeAuthenticator#challenge方法。 默认情况下,它设置响应状态并添加challengeRequest:

    ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(), ChallengeScheme.HTTP_BASIC, "realm") {
        public void challenge(org.restlet.Response response, boolean stale) {
            String requestedFrom = response.getRequest().getHeaders().getFirstValue("X-Requested-With");
            if (!"XMLHttpRequest".equals(requestedFrom)) {
                super.challenge(response, stale);
            } else {
                response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
            }

        };
    };