【问题标题】:Restlet 2.3 Override WWW-Authenticate HeaderRestlet 2.3 覆盖 WWW-Authenticate 标头
【发布时间】:2015-10-08 15:40:28
【问题描述】:

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

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

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

我想尝试并实现的是读取请求标头(很容易完成),如果存在 X-Requested-With: XMLHttpRequest 标头,我想在“401”响应中抑制 WWW-Authenticate 标头。

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

【问题讨论】:

    标签: java authentication restlet restlet-2.3.1


    【解决方案1】:

    在您的情况下,您应该使用过滤器从响应中删除标头 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;
        }
    }
    

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

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

    希望对你有帮助 蒂埃里

    【讨论】:

    • 谢谢蒂埃里,我没有意识到createInboundRoot() 中的过滤器createInboundRoot() 会在请求完成后处理响应。我解释文档的方式是 beforeHandleafterHandle 在过滤器处理的任一侧执行。即我认为订单是beforeHandle() -> handle() -> afterHandle() -> accessResource -> return response
    • 不客气!不,实际上是: beforeHandle -> next.handle() -> afterHandle ;-)
    【解决方案2】:

    另一种方法是覆盖 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);
                }
    
            };
        };
    

    【讨论】:

      猜你喜欢
      • 2016-06-02
      • 2018-10-19
      • 2021-06-07
      • 1970-01-01
      • 2014-04-10
      • 2012-10-12
      • 2021-03-09
      • 2021-10-21
      • 1970-01-01
      相关资源
      最近更新 更多