首先,配置https服務器須要一個證書,這個證書能夠從某些機構得到,也能夠本身經過工具生成。api
這樣的請求不會觸發Apple的相關代理方法 (URLSession:task:didReceiveChallenge:completionHandler:) 因此不管是AFNetWorking仍是Alamofire都不須要進行任何處理,便可正常使用。安全
AFSecurityPolicy分三種驗證模式:bash
AFSSLPinningModeCertificate 比較安全但也比較麻煩,它會比對你打包的證書跟服務器的證書是否一致。由於你的證書是跟 APP 一塊兒打包的,這也就表明說若是你的證書過時了或是變更了,你就得出一版新的 APP 並且舊版 APP 的證書就失效了。你也能夠在每次 APP 啓動時,就自動連到某個服務器下載最新的證書,不過此時這個下載連線就會是有風險的。服務器
AFSSLPinningModePublicKey 則是隻比對證書裏的 public key,因此即便服務器證書有所變更,只要 public key 不變,就能經過驗證。工具
因此若是你能確保每一個使用者老是使用最新版本的 APP(例如是公司企業內部專用的),那就能夠考慮AFSSLPinningModeCertificate,否則的話選擇 AFSSLPinningModePublicKey 是比較實際的做法。ui
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
/*
allowInvalidCertificates 是否容許無效證書(也就是自建的證書),默認爲NO
若是是須要驗證自建證書,須要設置爲YES
*/
securityPolicy.allowInvalidCertificates = YES;
/*
validatesDomainName 是否須要驗證域名,默認爲YES。
假如證書的域名與你請求的域名不一致,需把該項設置爲NO
主要用於這種狀況:客戶端請求的是子域名,而證書上的 是另一個域名。由於SSL證書上的域名是獨立的,假如證書上註冊的域名是www.google.com,那麼mail.google.com是沒法驗證經過的;固然,有錢能夠註冊通配符的域名*.google.com,但這個仍是比較貴的。
*/
securityPolicy.validatesDomainName = NO;
/*
validatesCertificateChain 是否驗證整個證書鏈,默認爲YES
設置爲YES,會將服務器返回的Trust Object上的證書鏈與本地導入的證書進行對比,這就意味着,假如你的證書鏈是這樣的:
GeoTrust Global CA
Google Internet Authority G2
*.google.com
那麼,除了導入*.google.com以外,還須要導入證書鏈上全部的CA證書(GeoTrust Global CA, Google Internet Authority G2);
如是自建證書的時候,能夠設置爲YES,加強安全性;假如是信任的CA所簽發的證書,則建議關閉該驗證;
*/
securityPolicy.validatesCertificateChain = NO;
複製代碼
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
/*
建立AFSecurityPolicy有兩種方式。
第一種方式是讓AFN在Bundle裏面自動尋找並嘗試匹配。
第二種方式是直接指定證書的位置
*/
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setValidatesDomainName:YES];
[securityPolicy setValidatesCertificateChain:NO];
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"name" ofType:@"cer"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setPinnedCertificates:@[certData]];
[securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setValidatesDomainName:YES];
[securityPolicy setValidatesCertificateChain:NO];
manager.securityPolicy = securityPolicy;
複製代碼
ServerTrustPolicy分六種驗證方式google
默認的策略,只有合法證書才能經過驗證lua
對註銷證書作的一種額外設置,不是很明白這裏,有興趣的朋友能夠最近查一下。spa
表明客戶端會將服務器端返回的證書和本地保存的證書中的【全部內容】,所有進行校驗;若是正確,才繼續進行。代理
表明客戶端會將服務器端返回的證書與本地保存的證書中的【PublicKey部分】進行校驗;若是正確,才繼續進行。
該選項下,驗證一直都是經過的,也就是說無條件信任
自定義驗證,須要返回一個布爾類型的結果
這裏最好是封裝一個SessionManger的單例進行統一處理。Swift的https驗證策略,支持一次對多個域名進行設置。
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"test.example.com": .pinCertificates(
certificates: ServerTrustPolicy.certificates(),
validateCertificateChain: true,
validateHost: true
),
"insecure.expired-apis.com": .disableEvaluation
]
let manger = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
複製代碼
這裏的設置是,針對test.example.com
域名進行pinCertificates
類型的驗證,並驗證證書鏈和域名地址。 針對insecure.expired-apis.com
域名進行disableEvaluation
類型的驗證。