当前位置: 首页 > 面试题库 >

使用NTLM进行身份验证时,HttpClient 4.1.1返回401,浏览器工作正常

龚威
2023-03-14
问题内容

我正在尝试使用Apache / Jakarta HttpClient
4.1.1使用给定的凭据连接到任意网页。为了测试这一点,我在运行只有一次身份验证模式的开发机上安装了IIS
7.5的最小安装。基本身份验证工作正常,但是每当我尝试登录时,摘要和NTLM都会返回401错误消息。这是我的代码:

    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpGet httpget = new HttpGet("http://localhost/"); 
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
            new NTCredentials("user", "password", "", "localhost"));
    if (!new File(System.getenv("windir") + "\\krb5.ini").exists()) {
        List<String> authtypes = new ArrayList<String>();
        authtypes.add(AuthPolicy.NTLM);
        authtypes.add(AuthPolicy.DIGEST);
        authtypes.add(AuthPolicy.BASIC);
        httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF,
                authtypes);
        httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF,
                authtypes);
    }
    localContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);
    HttpResponse response = httpclient.execute(httpget, localContext);
    System.out.println("Response code: " + response.getStatusLine());

我在Fiddler中注意到的一件事是Firefox与HttpClient发送的哈希值不同,这使我认为IIS
7.5可能期望比HttpClient提供的哈希更好?有任何想法吗?如果我可以验证它是否适用于NTLM,那就太好了。摘要也很好,但是如果有必要,我可以不用它。


问题答案:

我不是该主题的专家,但是在使用http组件进行NTLM身份验证期间,我发现客户端需要进行3次尝试才能连接到NTML端点。这里对Spnego进行了描述,但对于NTLM身份验证则有所不同。

对于第一次尝试使用NTLM的客户端,客户端将发出请求,Target auth state: UNCHALLENGED并且Web服务器将返回HTTP
401状态和标头:WWW-Authenticate: NTLM

客户端将检查配置的身份验证方案,应在客户端代码中配置NTLM。

第二次尝试,客户端将使用发送请求Target auth state: CHALLENGED,并发送带有以base64格式编码的令牌的授权标头:Authorization: NTLM TlRMTVNTUAABAAAAAYIIogAAAAAoAAAAAAAAACgAAAAFASgKAAAADw== 服务器再次返回HTTP
401状态,但标头:WWW-Authenticate: NTLM现在已填充编码信息。

3rd Attempt客户端将使用WWW-Authenticate: NTLM 标头中的信息,并通过Target auth state: HANDSHAKEAuthorization: NTLM包含服务器更多信息的授权标头进行最终请求。

就我而言,HTTP/1.1 200 OK之后我会收到。

为了避免所有请求文档中的所有问题,第4.7.1章指出,对于逻辑相关的请求,必须使用相同的执行令牌。对我来说,它没有用。

我的代码:我@PostConstruct使用EJB方法初始化一次客户端

        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(18);
        cm.setDefaultMaxPerRoute(6);

        RequestConfig requestConfig = RequestConfig.custom()
        .setSocketTimeout(30000)
        .setConnectTimeout(30000)
        .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM))
        .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
        .build();

        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new NTCredentials(userName, password, hostName, domainName));

        // Finally we instantiate the client. Client is a thread safe object and can be used by several threads at the same time. 
        // Client can be used for several request. The life span of the client must be equal to the life span of this EJB.
         this.httpclient = HttpClients.custom()
        .setConnectionManager(cm)
        .setDefaultCredentialsProvider(credentialsProvider)
        .setDefaultRequestConfig(requestConfig)
        .build();

在每个请求中使用相同的客户端实例:

            HttpPost httppost = new HttpPost(endPoint.trim());            
            // HttpClientContext is not thread safe, one per request must be created.
            HttpClientContext context = HttpClientContext.create();    
            response = this.httpclient.execute(httppost, context);

在我的EJB的@PreDestroy方法中,释放资源并将连接返回到连接管理器:

             this.httpclient.close();


 类似资料:
  • 问题内容: 有谁知道在自动化过程中使用Selenium或任何其他工具来处理浏览器身份验证吗? 问题答案: 警报方法authenticateUsing() 使您可以跳过“ Http基本身份验证”框。 从Selenium 3.4开始,它仍处于测试阶段 现在,仅针对 InternetExplorerDriver

  • 我试图通过NTLM代理发出请求,如下所示: 但它失败了,下面是日志: 环境类 操作系统:Windows 10 JRE: AdoptOpenJdk v11 代理类型:NTLM(Wingate) 问题上面的代码有问题吗? Obs相同的代码适用于Apache Http客户端v4.5.12

  • 问题内容: 尝试使用JavaMail中的NTLM连接到Exchange服务器。我可以连接到SMTP,但不能连接到IMAP。我还可以使用相同的主机/用户名/密码通过OS X Mail.app应用程序进行身份验证,帐户类型=“ IMAP”,端口143,ssl = false,authentication = NTLM,域名=“。 连接代码: 输出: 我尝试通过http://www.oracle.com

  • 问题内容: 我正在使用Spring 3 Web应用程序,因为Spring 3不支持NTLM身份验证,可以与Spring安全性一起使用的其他替代方法有哪些?这样,当用户登录到Active Directory时就可以通过应用程序进行身份验证了吗? 目前,Kerberos解决方案不是一个选择,NTLM是唯一的选择。 任何帮助都是非常明显的。 谢谢 问题答案: 我已经做过一次了。在这里抓住它。它将需要在A

  • 我相对来说是JMeter的新手,但是我很难让HTTP Sampler登陆到一个安全的网页上。我认为它需要NTLM认证,所以我使用HTTP授权管理器来传递BlazeMeter指南中指定的凭证 我的授权管理器具有以下值: 基本网址: https:// [测试站点] 用户名: [我的用户名] 密码: [我的密码] 域:与基本网址相同 机制: BASIC_DIGEST 然而,我只是得到一个401错误(见下

  • 我正在尝试使用urllib3连接到网页。代码如下所示。 如果我们假设url是需要使用用户名和密码进行身份验证的某个网页,那么我是否使用正确的代码进行身份验证? 我使用urllib2做这件事很舒服,但使用urllib3做不到同样的事情。 非常感谢