[- URLSession:didBecomeInvalidWithError:]
如果你使用finishTasksAndInvalidate函數(shù)使該session失效,那么session首先會先完成最后一個task,
然后再調(diào)用URLSession:didBecomeInvalidWithError:代理方法,
如果你調(diào)用invalidateAndCancel方法來使session失效,那么該session會立即調(diào)用上面的代理方法。
[- URLSession:didReceiveChallenge:completionHandler:]
web服務(wù)器接收到客戶端請求時,有時候需要先驗證客戶端是否為正常用戶,再決定是夠返回真實數(shù)據(jù)。
這種情況稱之為服務(wù)端要求客戶端接收挑戰(zhàn)(NSURLAuthenticationChallenge *challenge)。
接收到挑戰(zhàn)后,客戶端要根據(jù)服務(wù)端傳來的challenge來生成completionHandler所需的NSURLSessionAuthChallengeDisposition disposition和NSURLCredential *credential
(disposition指定應(yīng)對這個挑戰(zhàn)的方法,而credential是客戶端生成的挑戰(zhàn)證書,注意只有challenge中認(rèn)證方法為NSURLAuthenticationMethodServerTrust的時候,才需要生成挑戰(zhàn)證書)。
最后調(diào)用completionHandler回應(yīng)服務(wù)器端的挑戰(zhàn)。
如果你沒有實現(xiàn)該方法,該session會調(diào)用其NSURLSessionTaskDelegate的代理方法
URLSession:task:didReceiveChallenge:completionHandler:
- (void) URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
//挑戰(zhàn)處理類型為 默認(rèn)
/*
NSURLSessionAuthChallengePerformDefaultHandling:默認(rèn)方式處理
NSURLSessionAuthChallengeUseCredential:使用指定的證書
NSURLSessionAuthChallengeCancelAuthenticationChallenge:取消挑戰(zhàn)
*/
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__block NSURLCredential *credential = nil;
// sessionDidReceiveAuthenticationChallenge是自定義方法,用來如何應(yīng)對服務(wù)器端的認(rèn)證挑戰(zhàn)
if (self.sessionDidReceiveAuthenticationChallenge) {
disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
} else {
// 此處服務(wù)器要求客戶端的接收認(rèn)證挑戰(zhàn)方法是NSURLAuthenticationMethodServerTrust
// 也就是說服務(wù)器端需要客戶端返回一個根據(jù)認(rèn)證挑戰(zhàn)的保護空間提供的信任(即challenge.protectionSpace.serverTrust)產(chǎn)生的挑戰(zhàn)證書。
// 而這個證書就需要使用credentialForTrust:來創(chuàng)建一個NSURLCredential對象
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
// 基于客戶端的安全策略來決定是否信任該服務(wù)器,不信任的話,也就沒必要響應(yīng)挑戰(zhàn)
if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
// 創(chuàng)建挑戰(zhàn)證書(注:挑戰(zhàn)方式為UseCredential和PerformDefaultHandling都需要新建挑戰(zhàn)證書)
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
// 確定挑戰(zhàn)的方式
if (credential) {
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
// 取消挑戰(zhàn)
disposition = NSURLSessionAuthChallengeRejectProtectionSpace;
}
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
}
// 必須調(diào)用此方法,完成認(rèn)證挑戰(zhàn)
if (completionHandler) {
completionHandler(disposition, credential);
}
}
響應(yīng)認(rèn)證
可以在
URLSession:didReceiveChallenge:completionHandler:
或
URLSession:task:didReceiveChallenge:completionHandler:
代理方法中響應(yīng)認(rèn)證。
提供憑據(jù)
認(rèn)證需要創(chuàng)建一個服務(wù)器期望的NSURLCredential對象,該對象可以通過 authenticationMethod 來制定認(rèn)證方式。下面是幾種認(rèn)證方式:
- HTTP基本認(rèn)證(NSURLAuthenticationMethodHTTPBasic)需要用戶名和密碼。通過如下創(chuàng)建NSURLCredential對象;
credentialWithUser: password:persistence:
- HTTP摘要認(rèn)證(NSURLAuthenticationMethodHTTPDigest),類似于基本認(rèn)證,不過在提供用戶名和秘密后,摘要會自動生成。
通過如下創(chuàng)建NSURLCredential對象;
credentialWithUser: password:persistence:.
- 客戶端證書認(rèn)證(NSURLAuthenticationMethodClientCertificate)需要系統(tǒng)識別出所有服務(wù)器需要的證書。
通過如下創(chuàng)建NSURLCredential對象;
credentialWithIdentity:certificates:persistence:
- 服務(wù)器信任認(rèn)證(NSURLAuthenticationMethodServerTrust)需要一個信任對象,
通過創(chuàng)建NSURLCredential對象。
credentialForTrust:
在創(chuàng)建完NSURLCredential對象后,將該對象傳遞給對應(yīng)的完成處理句柄。
繼續(xù)無憑據(jù)
如果代理方法不能提供有效憑據(jù),可以嘗試?yán)^續(xù)無憑據(jù)訪問。可將下面兩個值之一傳給完成句柄:
NSURLSessionAuthChallengePerformDefaultHandling 處理請求就像代理沒有提供處理認(rèn)證的代理方法一樣。
NSURLSessionAuthChallengeRejectProtectionSpace 拒絕認(rèn)證。根據(jù)服務(wù)器的響應(yīng),URL loading class可能會在多個受保護的空間進行多次調(diào)用該代理方法。
取消認(rèn)證
將值NSURLSessionAuthChallengeCancelAuthenticationChallenge 傳遞給完成句柄即可。