2016-12-27 86 views
0

我正在運行樣本Apache hc(http客戶端)進行摘要式身份驗證。我沒有改變什麼,只是使用所提供的樣本:Apache HTTP客戶端樣本無法進行摘要式身份驗證

public static void main(String[] args) throws Exception { 
    HttpHost target = new HttpHost("httpbin.org", 80, "http"); 
    CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
    credsProvider.setCredentials(
      new AuthScope(target.getHostName(), target.getPort()), 
      new UsernamePasswordCredentials("user", "passwd")); 
    CloseableHttpClient httpclient = HttpClients.custom() 
      .setDefaultCredentialsProvider(credsProvider) 
      .build(); 
    try { 

     // Create AuthCache instance 
     AuthCache authCache = new BasicAuthCache(); 
     // Generate DIGEST scheme object, initialize it and add it to the local 
     // auth cache 
     DigestScheme digestAuth = new DigestScheme(); 
     // Suppose we already know the realm name 
     digestAuth.overrideParamter("realm", "[email protected]"); 
     // Suppose we already know the expected nonce value 
     digestAuth.overrideParamter("nonce", "b2c603bb7c93cfa197945553a1044283"); 
     authCache.put(target, digestAuth); 

     // Add AuthCache to the execution context 
     HttpClientContext localContext = HttpClientContext.create(); 
     localContext.setAuthCache(authCache); 

     HttpGet httpget = new HttpGet("http://httpbin.org/digest-auth/auth/user/passwd"); 

     System.out.println("Executing request " + httpget.getRequestLine() + " to target " + target); 
     for (int i = 0; i < 3; i++) { 
      CloseableHttpResponse response = httpclient.execute(target, httpget, localContext); 
      try { 
       System.out.println("----------------------------------------"); 
       System.out.println(response.getStatusLine()); 
       System.out.println(EntityUtils.toString(response.getEntity())); 
      } finally { 
       response.close(); 
      } 
     } 
    } finally { 
     httpclient.close(); 
    } 
} 

而且我越來越:HTTP/1.1 401未經授權

如果我直接去找http://httpbin.org/digest-auth/auth/user/passwd在提示我要用戶/ passwd文件,然後提供這一頁。所以這個網站是正確的。

任何想法是什麼錯?我有最新版本的圖書館。

的Fiddler驗證爲瀏覽器(成功):

無代理授權報頭的存在。

認證頭存在:文摘名= 「用戶」, 境界= 「[email protected]」,隨機數= 「8ada87344eb5a10bf810bcc211205c24」, URI = 「/消化-AUTH/AUTH /用戶/ passwd的」, 響應= 「ad22423e5591d14c90c6fe3cd762e64c」, 不透明= 「361645844d957289c4c8f3479f76269f」,QOP = AUTH,NC = 00000001, cnonce = 「260d8ddfe64bf32e」

提琴手驗證了我的代碼(失敗):

無代理-Authorizati在標題上。

認證頭存在:文摘名= 「用戶」, 境界= 「[email protected]」,隨機數= 「76af6c9c0a1f57ee5f0fcade2a5f758c」, URI =「http://httpbin.org/digest-auth/auth /用戶/ passwd的」, 響應= 「745686e3f38ab40ce5907d41f91823e6」,QOP = AUTH,NC = 00000001, cnonce = 「634b618d5c8ac9af」,算法= MD5, 不透明= 「fe84ce11c48a7b258490600800e5e6df」

回答

0

此代碼digestAuth.overrideParamter("realm", "some realm")應該有一些請用您的服務器域替換"some realm"。請查看此question

+0

如何以編程方式確定領域?此代碼適用於將連接到許多服務器的許多計算機上運行的庫。所以我不能硬編碼。 –

0

好吧,我得到它的工作。你也必須設置一個cookie。 Thanks to this post尋求幫助。下面的代碼工作 - 但只有當你使用Fiddler時而不是

public static void main(String[] args) throws Exception { 

     CookieStore cookieStore = new BasicCookieStore(); 
     BasicClientCookie cookie = new BasicClientCookie("fake", "fake_value"); 
     cookie.setDomain("httpbin.org"); 
     cookie.setPath("/"); 
     cookieStore.addCookie(cookie); 

     // https://stackoverflow.com/questions/27291842/digest-auth-with-java-apache-client-always-401-unauthorized 

     HttpHost target = new HttpHost("httpbin.org", 80, "http"); 
     CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
     credsProvider.setCredentials(
       new AuthScope(target.getHostName(), target.getPort()), 
       new UsernamePasswordCredentials("user", "passwd")); 

     CloseableHttpClient httpclient = HttpClients.custom() 
       .setDefaultCookieStore(cookieStore) 
       .setDefaultCredentialsProvider(credsProvider) 
//    .setProxy(new HttpHost("127.0.0.1", 8888)) 
       .build(); 
     try { 

      // Create AuthCache instance 
      AuthCache authCache = new BasicAuthCache(); 
      // Generate DIGEST scheme object, initialize it and add it to the local 
      // auth cache 
      DigestScheme digestAuth = new DigestScheme(); 
      // Suppose we already know the realm name 
      digestAuth.overrideParamter("realm", "[email protected]"); 
      // Suppose we already know the expected nonce value 
      digestAuth.overrideParamter("nonce", calculateNonce()); 
      authCache.put(target, digestAuth); 

      // Add AuthCache to the execution context 
      HttpClientContext localContext = HttpClientContext.create(); 
      localContext.setAuthCache(authCache); 

      HttpGet httpget = new HttpGet("http://httpbin.org/digest-auth/auth/user/passwd"); 

      System.out.println("Executing request " + httpget.getRequestLine() + " to target " + target); 
       CloseableHttpResponse response = httpclient.execute(target, httpget, localContext); 
       try { 
        System.out.println("----------------------------------------"); 
        System.out.println(response.getStatusLine()); 
        System.out.println(EntityUtils.toString(response.getEntity())); 
       } finally { 
        response.close(); 
       } 
     } finally { 
      httpclient.close(); 
     } 
    } 

    public static synchronized String calculateNonce() { 

     Date d = new Date(); 
     SimpleDateFormat f = new SimpleDateFormat("yyyy:MM:dd:hh:mm:ss"); 
     String fmtDate = f.format(d); 
     Random rand = new Random(100000); 
     Integer randomInt = rand.nextInt(); 
     return org.apache.commons.codec.digest.DigestUtils.md5Hex(fmtDate + randomInt.toString()); 
    } 
相關問題