<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
    第四章 HTTP認證
    HttpClient提供對由HTTP標準規(guī)范定義的認證模式的完全支持。HttpClient的認證框架可以擴展支持非標準的認證模式,比如NTLM和SPNEGO。

    4.1 用戶憑證

    任何用戶身份驗證的過程都需要一組可以用于建立用戶身份的憑據。用戶憑證的最簡單的形式可以僅僅是用戶名/密碼對。UsernamePasswordCredentials代表了一組包含安全規(guī)則和明文密碼的憑據。這個實現對由HTTP標準規(guī)范中定義的標準認證模式是足夠的

    UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
    System.out.println(creds.getUserPrincipal().getName());
    System.out.println(creds.getPassword());

    輸出內容為:

    user
    pwd

    NTCredentials是微軟Windows指定的實現,它包含了除了用戶名/密碼對外,一組額外的Windows指定的屬性,比如用戶域名的名字,比如在微軟的Windows網絡中,相同的用戶使用不同設置的認證可以屬于不同的域。

    NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
    System.out.println(creds.getUserPrincipal().getName());
    System.out.println(creds.getPassword());

    輸出內容為:

    DOMAIN/user
    pwd

    4.2 認證模式

    AuthScheme接口代表了抽象的,面向挑戰(zhàn)-響應的認證模式。一個認證模式期望支持如下的功能:
    • 解析和處理由目標服務器在對受保護資源請求的響應中發(fā)回的挑戰(zhàn)。
    • 提供處理挑戰(zhàn)的屬性:認證模式類型和它的參數,如果可用,比如這個認證模型可應用的領域。
    • 對給定的憑證組和HTTP請求對響應真實認證挑戰(zhàn)生成認證字符串。
    要注意認證模式可能是有狀態(tài)的,涉及一系列的挑戰(zhàn)-響應交流。HttpClient附帶了一些AuthScheme實現:
    • Basic(基本):Basic認證模式定義在RFC 2617中。這個認證模式是不安全的,因為憑據以明文形式傳送。盡管它不安全,如果用在和TLS/SSL加密的組合中,Basic認證模式是完全夠用的。
    • Digest(摘要):Digest認證模式定義在RFC 2617中。Digest認證模式比Basic有顯著的安全提升,對不想通過TLS/SL加密在完全運輸安全上開銷的應用程序來說也是很好的選擇。
    • NTLM:NTLM是一個由微軟開發(fā)的優(yōu)化Windows平臺的專有認證模式。NTLM被認為是比Digest更安全的模式。這個模式需要外部的NTLM引擎來工作。要獲取更多詳情請參考包含在HttpClient發(fā)布包中的NTLM_SUPPORT.txt文檔。

    4.3 HTTP認證參數

    有一些可以用于定制HTTP認證過程和獨立認證模式行為的參數:
    • 'http.protocol.handle-authentication':定義了是否認證應該被自動處理。這個參數期望的得到一個java.lang.Boolean類型的值。如果這個參數沒有被設置,HttpClient將會自動處理認證。
    • 'http.auth.credential-charset':定義了當編碼用戶憑證時使用的字符集。這個參數期望得到一個java.lang.String類型的值。如果這個參數沒有被設置,那么就會使用US-ASCII。

    4.4 認證模式注冊表

    HttpClient使用AuthSchemeRegistry類維護一個可用的認證模式的注冊表。對于每個默認的下面的模式是注冊過的:
    • Basic:基本認證模式
    • Digest:摘要認證模式
    請注意NTLM模式沒有對每個默認的進行注冊。NTLM不能對每個默認開啟是應為許可和法律上的原因。要獲取更詳細的關于如何開啟NTLM支持的內容請看這部分。

    4.5 憑據提供器

    憑據提供器意來維護一組用戶憑據,還有能夠對特定認證范圍生產用戶憑據。認證范圍包括主機名,端口號,領域名稱和認證模式名稱。當使用憑據提供器來注冊憑據時,我們可以提供一個通配符(任意主機,任意端口,任意領域,任意模式)來替代確定的屬性值。如果直接匹配沒有發(fā)現,憑據提供器期望被用來發(fā)現最匹配的特定范圍。

    HttpClient可以和任意實現了CredentialsProvider接口的憑據提供器的物理代表一同工作。默認的CredentialsProvider實現被稱為BasicCredentialsProvider,它是簡單的憑借java.util.HashMap的實現。
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(
    new AuthScope("somehost", AuthScope.ANY_PORT),
    new UsernamePasswordCredentials("u1", "p1"));
    credsProvider.setCredentials(
    new AuthScope("somehost", 8080),
    new UsernamePasswordCredentials("u2", "p2"));
    credsProvider.setCredentials(
    new AuthScope("otherhost", 8080, AuthScope.ANY_REALM, "ntlm"),
    new UsernamePasswordCredentials("u3", "p3"));
    System.out.println(credsProvider.getCredentials(
    new AuthScope("somehost", 80, "realm", "basic")));
    System.out.println(credsProvider.getCredentials(
    new AuthScope("somehost", 8080, "realm", "basic")));
    System.out.println(credsProvider.getCredentials(
    new AuthScope("otherhost", 8080, "realm", "basic")));
    System.out.println(credsProvider.getCredentials(
    new AuthScope("otherhost", 8080, null, "ntlm")));

    輸出內容為:

    [principal: u1]
    [principal: u2]
    null
    [principal: u3]

    4.6 HTTP認證和執(zhí)行上下文

    HttpClient依賴于AuthState類來跟蹤關于認證過程狀態(tài)的詳細信息。在HTTP請求執(zhí)行過程中,HttpClient創(chuàng)建2個AuthState的實例:一個對于目標主機認證,另外一個對于代理認證。如果目標服務器或代理需要用戶認證,那么各自的AuthState實例將會被在認證處理過程中使用的AuthScope,AuthScheme和Crednetials來填充。AuthState可以被檢查來找出請求的認證是什么類型的,是否匹配AuthScheme的實現,是否憑據提供器對給定的認證范圍去找用戶憑據。

    在HTTP請求執(zhí)行的過程中,HttpClient添加了下列和認證相關的對象到執(zhí)行上下文中:

    • 'http.authscheme-registry':AuthSchemeRegistry實例代表真實的認證模式注冊表。在本地內容中設置的這個屬性的值優(yōu)先于默認的。
    • 'http.auth.credentials-provider':CookieSpec實例代表了真實的憑據提供器。在本地內容中設置的這個屬性的值優(yōu)先于默認的。
    • 'http.auth.target-scope':AuthState實例代表了真實的目標認證狀態(tài)。在本地內容中設置的這個屬性的值優(yōu)先于默認的。
    • 'http.auth.proxy-scope':AuthState實例代表了真實的代理認證狀態(tài)。在本地內容中設置的這個屬性的值優(yōu)先于默認的。

    本地的HttpContext對象可以用于定制HTTP認證內容,并先于請求執(zhí)行或在請求被執(zhí)行之后檢查它的狀態(tài):

    HttpClient httpclient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpGet httpget = new HttpGet("http://localhost:8080/");
    HttpResponse response = httpclient.execute(httpget, localContext);
    AuthState proxyAuthState = (AuthState) localContext.getAttribute(
    ClientContext.PROXY_AUTH_STATE);
    System.out.println("Proxy auth scope: " + proxyAuthState.getAuthScope());
    System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
    System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
    AuthState targetAuthState = (AuthState) localContext.getAttribute(
    ClientContext.TARGET_AUTH_STATE);
    System.out.println("Target auth scope: " + targetAuthState.getAuthScope());
    System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
    System.out.println("Target auth credentials: " + targetAuthState.getCredentials());

    4.7 搶占認證

    HttpClient不支持開箱的搶占認證,因為濫用或重用不正確的搶占認證可能會導致嚴重的安全問題,比如將用戶憑據以明文形式發(fā)送給未認證的第三方。因此,用戶期望評估搶占認證和在它們只能應用程序環(huán)境內容安全風險潛在的好處,而且要求使用如協議攔截器的標準HttpClient擴展機制添加對搶占認證的支持。

    這是一個簡單的協議攔截器,如果沒有企圖認證,來搶先引入BasicScheme的實例到執(zhí)行上下文中。請注意攔截器必須在標準認證攔截器之前加入到協議處理鏈中。

    HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {
    public void process(final HttpRequest request,
    final HttpContext context) throws HttpException, IOException {
    AuthState authState = (AuthState) context.getAttribute(
    ClientContext.TARGET_AUTH_STATE);
    CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
    HttpHost targetHost = (HttpHost) context.getAttribute(
    ExecutionContext.HTTP_TARGET_HOST);
    // 如果沒有初始化auth模式
    if (authState.getAuthScheme() == null) {
    AuthScope authScope = new AuthScope(
    targetHost.getHostName(),
    targetHost.getPort());
    // 獲得匹配目標主機的憑據
    Credentials creds = credsProvider.getCredentials(authScope);
    // 如果發(fā)現了,搶先生成BasicScheme
    if (creds != null) {
    authState.setAuthScheme(new BasicScheme());
    authState.setCredentials(creds);
    }
    }
    }
    };
    DefaultHttpClient httpclient = new DefaultHttpClient();
    // 作為第一個攔截器加入到協議鏈中
    httpclient.addRequestInterceptor(preemptiveAuth, 0);

    4.8 NTLM 認證

    當前HttpClient沒有提對開箱的NTLM認證模式的支持也可能永遠也不會。這個原因是法律上的而不是技術上的。然而,NTLM認證可以使用外部的NTLM引擎比如JCIFS[http://jcifs.samba.org/]來開啟,類庫由Samba[http://www.samba.org/]項目開發(fā),作為它們Windows的交互操作程序套裝的一部分。要獲取詳細內容請參考HttpClient發(fā)行包中包含的NTLM_SUPPORT.txt文檔。

    4.8.1 NTLM連接持久化

    NTLM認證模式是在計算開銷方面昂貴的多的,而且對標準的Basic和Digest模式的性能影響也很大。這很可能是為什么微軟選擇NTLM認證模式為有狀態(tài)的主要原因之一。也就是說,一旦認證通過,用戶標識是和連接的整個生命周期相關聯的。NTLM連接的狀態(tài)特性使得連接持久化非常復雜,對于明顯的原因,持久化NTLM連接不能被使用不同用戶標識的用戶重用。標準的連接管理器附帶HttpClient是完全能夠管理狀態(tài)連接的。而邏輯相關的,使用同一session和執(zhí)行上下文為了讓它們了解到當前的用戶標識的請求也是極為重要的。否則,HttpClient將會終止對每個基于NTLM保護資源的HTTP請求創(chuàng)建新的HTTP連接。要獲取關于有狀態(tài)的HTTP連接的詳細討論,請參考這個部分。

    因為NTLM連接是有狀態(tài)的,通常建議使用相對簡單的方法觸發(fā)NTLM認證,比如GET或HEAD,而重用相同的連接來執(zhí)行代價更大的方法,特別是它們包含請求實體,比如POST或PUT。

    DefaultHttpClient httpclient = new DefaultHttpClient();
    NTCredentials creds = new NTCredentials("user", "pwd", "myworkstation", "microsoft.com");
    httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
    HttpHost target = new HttpHost("www.microsoft.com", 80, "http");
    // 保證相同的內容來用于執(zhí)行邏輯相關的請求
    HttpContext localContext = new BasicHttpContext();
    // 首先執(zhí)行簡便的方法。這會觸發(fā)NTLM認證
    HttpGet httpget = new HttpGet("/ntlm-protected/info");
    HttpResponse response1 = httpclient.execute(target, httpget, localContext);
    HttpEntity entity1 = response1.getEntity();
    if (entity1 != null) {
    entity1.consumeContent();
    }
    //之后使用相同的內容(和連接)執(zhí)行開銷大的方法。
    HttpPost httppost = new HttpPost("/ntlm-protected/form");
    httppost.setEntity(new StringEntity("lots and lots of data"));
    HttpResponse response2 = httpclient.execute(target, httppost, localContext);
    HttpEntity entity2 = response2.getEntity();
    if (entity2 != null) {
    entity2.consumeContent();
    }

     



    轉載自:http://www.cnblogs.com/loveyakamoz/archive/2011/07/21/2113247.html
    posted on 2012-09-26 16:44 abin 閱讀(831) 評論(0)  編輯  收藏 所屬分類: httpClient
    主站蜘蛛池模板: 羞羞网站免费观看| 91香蕉国产线观看免费全集| 亚洲国产精品乱码一区二区| 四虎永久在线观看免费网站网址 | www.亚洲成在线| 日韩免费视频播放| 丁香花在线视频观看免费| 亚洲91精品麻豆国产系列在线| 亚洲 国产 图片| 1000部啪啪未满十八勿入免费| 粉色视频成年免费人15次| 久久夜色精品国产嚕嚕亚洲av| 久久久亚洲精品国产| 免费阿v网站在线观看g| 国产免费黄色无码视频| 亚洲人成77777在线播放网站不卡| 亚洲爽爽一区二区三区| 成人黄18免费视频| 七色永久性tv网站免费看| 国产AV日韩A∨亚洲AV电影 | 国产亚洲福利在线视频| 亚洲成av人在线视| 免费观看国产小粉嫩喷水| 国产高清不卡免费在线| XXX2高清在线观看免费视频| 亚洲精品国产精品| 亚洲国产美女精品久久久久| 国产亚洲精品xxx| 亚洲av日韩av欧v在线天堂| 成人毛片18女人毛片免费| 日韩内射激情视频在线播放免费| 男人j进女人p免费视频| 亚洲日韩国产AV无码无码精品 | 亚洲欧洲日韩国产综合在线二区| 日韩精品亚洲专区在线观看| 国产在线观看免费观看不卡| 亚洲精品免费视频| a级毛片毛片免费观看永久| 西西人体大胆免费视频| 亚洲JLZZJLZZ少妇| 亚洲永久网址在线观看|