2009-11-20 219 views
36

我想通過UIWebView訪問一個安全的網站。當我通過Safari瀏覽器訪問它時,我遇到了身份驗證挑戰,但在應用程序中我的UIWebView中未顯示相同內容。我怎樣才能讓它出現?如何在UIWebView中顯示身份驗證挑戰?

任何指針,示例代碼或鏈接將非常有幫助。非常感謝。

回答

35

這實際上是超級簡單的...我相信你可以在顯示auth挑戰委託時顯示一個UIAlertView(或者在加載URL之前,如果你確信你正在點擊的URL會提示用於身份驗證登錄信息)。無論如何,訣竅是創建你自己的NSURLConnection,我做一些邏輯來保存auth委託是否被使用。作爲y5h說以及

,加上`_authed = YES」到didReceiveResponse方法,將停止無限循環:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 
{ 
    NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authed); 

    if (!_authed) { 
     _authed = NO; 
     /* pretty sure i'm leaking here, leave me alone... i just happen to leak sometimes */ 
     [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
     return NO; 
    } 

    return YES; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; 
{ 
    NSLog(@"got auth challange"); 

    if ([challenge previousFailureCount] == 0) { 
     _authed = YES; 
     /* SET YOUR credentials, i'm just hard coding them in, tweak as necessary */ 
     [[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"username" password:@"password" persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge]; 
    } else { 
     [[challenge sender] cancelAuthenticationChallenge:challenge]; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; 
{ 
    NSLog(@"received response via nsurlconnection"); 

    /** THIS IS WHERE YOU SET MAKE THE NEW REQUEST TO UIWebView, which will use the new saved auth info **/ 

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:]]; 

    [_webView loadRequest:urlRequest]; 
} 

- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection; 
{ 
    return NO; 
} 
+2

不適用於POST。即使對此的簡單修改仍然不適用於POST。 – 2010-10-16 01:30:38

+2

這對於任何未經過身份驗證的請求都無效(_authed always == NO並觸發無限循環)。即使您解決了該問題,但仍無法正常工作,因爲每個網頁都會觸發shouldStartLoadWithRequest多次,最終導致上次請求的網頁視圖加載爲網頁視圖中顯示的唯一內容。 – Zach 2011-04-22 05:02:08

+1

將「_authed = YES」添加到didReceiveResponse。這可以防止服務器由於某種原因未發送質詢請求時的無限循環。 – Seunghoon 2011-10-11 08:43:10

4

如你所知,UIWebView不提供與服務器通信的機會。 我這樣解決了這個問題:在UIWebView的委託方法shouldStartLoadWithRequest中,我使用NSURLConnection啓動另一個連接,並且已經在委託NSURLConnection didReceiveAuthenticationChallenge的方法中處理了來自服務器的挑戰。在方法didReceiveResponse(如果挑戰來臨),然後再次在同一個UIWebView加載相同的URL(挑戰已經被處理:)。不要忘記取消didReceiveResponse中的連接,否則會使流量增加一倍。

+2

如果您已收到回覆,取消連接將如何防止流量翻倍? – Travis 2013-10-22 21:06:34

1

如果你正在經歷的是什麼扎克在薩赫勒的回答的註釋中描述的症狀。即使身份驗證失敗,您也需要將其視爲已驗證身份,因此如果不需要身份驗證,如果真的需要身份驗證,它會嘗試繼續加載頁面,然後它會像正常情況一樣失敗。

第二個症狀,其中shouldStartLoadWithRequest:觸發多次(由於網頁上嵌入的內容),它只會顯示的最後一件事是加載,而不是整個頁面,這樣做:

shouldStartLoadWithRequest:方法,將其添加到頂部

if(webview.loading){ //if url requests come through while its loading, its probably embedded content 
    return YES; 
} 

編輯:這上面的方法有問題,如果頁面完全加載,然後加載更多的嵌入式內容之後,與Facebook打破這是唯一的情況下,香港專業教育學院看到,到目前爲止

這會讓網站在嘗試加載時通過網址。即時通訊不確定是否可以安全地假定在初始請求後的每個網址都是嵌入內容,但爲了我的目的,它似乎可以正常工作,所以也許它也適合您。

此外,使用

- (void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

因爲

connection:canAuthenticateAgainstProtectionSpace: 
connection:didReciveAuthenticationChallenge: 
connection:didCancelAuthenticationChallenge: 

被depricated,對我來說,你不能以https網站使用它們

4

您也可以提供對您的憑據進行身份驗證網址。 只需在'http://'和'頁面url'之間添加用戶名和密碼即可。

NSString *urlString = @"http://username:[email protected]/home"; 
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]]; 
+0

這有多安全? – 2014-06-30 03:25:55

+1

同一網絡上的某個人可以清楚地看到請求。 =>使用https和SSL證書可以解決此問題。 你可以用Wireshark等嗅探器來檢查。 – 2014-09-12 19:44:32

0

我想用下面的吊艙建議另一個答案: https://github.com/jivesoftware/JiveAuthenticatingHTTPProtocol

它包含展示如何使用UIAlertView索要密碼的用戶的例子,可以很容易地適應返回例如,從本地數據庫保存的密碼。

聲明:我與Jive沒有任何關係,也沒有參加過,這只是一個工具的建議,這個工具在爲此奮鬥了幾天後幫助了我。

相關問題