源码分析之AFNetworking③AFSecurityPolicy和AFURLRequestSerialization

Posted 梦想家-mxj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码分析之AFNetworking③AFSecurityPolicy和AFURLRequestSerialization相关的知识,希望对你有一定的参考价值。

一、首先看一下AFSecurityPolicy的属性:
1、https验证模式,默认无,还有证书匹配和公钥匹配
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
AFSSLPinningModeNone,
AFSSLPinningModePublicKey,
AFSSLPinningModeCertificate,
};
可以匹配证书验证的证书,当我们不主动设置SSLPinningMode的时候该字段是空;
如果主动设置,会调用默认读取certificatesInBundle.cer的证书进行赋值。
2、
@property (nonatomic, strong, nullable) NSSet <NSData *> pinnedCertificates;
//3、是否允许无效证书(即自建证书),默认NO,如果需要验证自建证书设置为YES
@property (nonatomic, assign) BOOL allowInvalidCertificates;
//4、是否需要验证域名;如设置成NO的话,即服务器使用其他可信任机构颁发的证书,也可以连接,这危险,建议打开
@property (nonatomic, assign) BOOL validatesDomainName;
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名
.google.com,但这个还是比较贵的。//如置为NO,建议自己添加对应域名的校验逻辑

核心代码

- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{//挑战处理类型为 默认
    /*
     NSURLSessionAuthChallengePerformDefaultHandling:默认方式处理
     NSURLSessionAuthChallengeUseCredential:使用指定的证书
     NSURLSessionAuthChallengeCancelAuthenticationChallenge:取消挑战     */
    NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;    // 服务器挑战的证书
    __block NSURLCredential *credential = nil;// 这个Block是提供给用户自定义证书挑战方式的,比如是否需要自定义
    if (self.sessionDidReceiveAuthenticationChallenge) {
        disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
    } else {    // NSURLAuthenticationMethodServerTrust 单向认证关系 也就是说服务器端需要客户端返回一个根据认证挑战的保护空间提供的信任产生的挑战证书
        if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {        // 基于客户端的安全策略来决定是否信任该服务器,不信任的话,也就没必要响应挑战
            if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {             // 创建挑战证书(注:挑战方式为UseCredential和PerformDefaultHandling都需要新建挑战证书)
                credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];                if (credential) {
                    disposition = NSURLSessionAuthChallengeUseCredential;
                } else {
                    disposition = NSURLSessionAuthChallengePerformDefaultHandling;
                }
            } else {
                disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
            }
        } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
    }// 完成挑战
    if (completionHandler) {
        completionHandler(disposition, credential);
    }
}

二、AFURLRequestSerialization
AFURLRequestSerialization涉及两个模块:AFURLRequestSerialization和AFURLResponseSerialization
前者主要是修改请求头部,提供了接口设置HTTP头部字段,后者是处理响应的模块,将请求放回的数据解析成相对应的格式。

以上是关于源码分析之AFNetworking③AFSecurityPolicy和AFURLRequestSerialization的主要内容,如果未能解决你的问题,请参考以下文章

源码分析之AFNetworking③AFSecurityPolicy和AFURLRequestSerialization

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking④UIkit+AFNetworking

源码分析之AFNetworking ②AFNetworkReachabilityManager