NSURLAuthenticationChallenge官方文档
NSURLAuthenticationChallenge
Overview
NSURLAuthenticationChallenge封装了服务器需要验证客户端的证书。
大多数应用不会创建NSURLAuthenticationChallenge。但是,作为自定义NSURLProtocol子类的一部分,我们可能需要在对自定义网络协议的支持时创建此身份认证对象。
相反,你的应用会在各种NSURLSession,NSURLConnection和NSURLDownload的代理方法中收到身份验证问题,例如URLSession:task:didReceiveChallenge:completionHandler:
。这些对象提供了如何处理服务器身份验证请求时需要的信息。身份认证的核心是定义所请求的身份验证类型,主机和端口号,网络协议以及(在适用的情况下)认证领域(同一服务器上的一组相关URL)一套凭证)的保护空间,。
你可以通过提供NSURLCredential对象来做身份验证工作。具体怎么处理取决于你使用的API和认证类型。
高级用法,如果你将用户的凭据提供给服务器或代理,调用proposedCredential
将在保护空间中(处理请求的NSURLCredentialStorage如果存在这样的证书)取出符合标准的证书 。
如果previousFailureCount
方法返回0并且证书存在,则说明证书还未用过,这意味着您应该尝试使用这个证书。如果它返回非零结果,则服务器拒绝了证书,你应该使用该凭据来填充密码或证书选择器对话框,然后提供新的证书。你可以通过调用credentialWithUser:password:persistence:
方法来创建基于密码的证书,或者使用credentialWithIdentity: certificates:persistence:
来创建基于证书的凭据.
如果身份验证的保护空间使用NSURLAuthenticationMethodServerTrust身份验证方法,则该请求将要求你验证服务器的真实性。在这种情况下,proposalCredential
方法提供基于服务器作为其初始TLS握手的一部分提供的证书的证书。大多数应用程序应根据服务器信任保护空间请求对身份认证的默认处理,但如果需要覆盖默认的TLS验证行为,可以参考Overriding TLS Chain Validation Correctly。
Symbols
Creating an authentication challenge instance
-
- (instancetype)initWithAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge sender:(id<NSURLAuthenticationChallengeSender>)sender
使用指定的challenge和sender初始化的NSURLAuthenticationChallenge对象。
challenge:要复制的NSURLAuthenticationChallenge对象;
sender:你要用于新对象的sender。 通常发件人是你定制的NSURLProtocol子类的实例来调用此方法。大多数应用程序不会自己创建身份认证证书。 但是,作为自定义NSURLProtocol子类的一部分,你可能需要在添加对自定义网络协议的支持时创建身份认证对象。
当对现有NSURLProtocol进行子类化时,此方法可以修改现有类所发出的认证,以便子类接收到对这些认证的响应。
-
- (instancetype)initWithProtectionSpace:(NSURLProtectionSpace *)space proposedCredential:(NSURLCredential *)credential previousFailureCount:(NSInteger)previousFailureCount failureResponse:(NSURLResponse *)response error:(NSError *)error sender:(id<NSURLAuthenticationChallengeSender>)sender
返回指定保护空间,证书,失败次数,服务器响应,错误和sender的初始化的NSURLAuthenticationChallenge对象。
space:URL认证的保护空间。 这提供了关于认证请求的附加信息,例如主机,端口,认证领域等。
credential:给出的证书;可为nil
previousFailureCount:此请求的先前失败的总数,包括其他保护空间的失败。
response:包含导致生成身份认证的服务器响应的NSURLResponse对象,如果没有响应对象适用于该认证,则为nil。
error:描述身份验证失败的NSError对象,如果不适用于认证,则为nil。
sender:发起验证挑战的对象(通常是调用此方法的对象)。
Getting authentication challenge properties
-
@property(readonly, copy) NSError *error
表示上次身份验证失败的错误对象。
如果协议没有使用错误来指示身份验证失败,则此方法返回nil。
-
@property(readonly, copy) NSURLResponse *failureResponse
表示上次身份验证失败的URL响应对象。
如果协议没有使用NSURLResponse来指示身份验证失败,则此方法返回nil。
-
@property(readonly) NSInteger previousFailureCount
调用者的身份验证失败次数。
以前的失败计数包括所有保护空间的失败次数,而不仅仅是当前的请求。
-
@property(readonly, copy) NSURLCredential *proposedCredential
给到认证的证书;
如果此认证没有默认证书,则此方法返回nil。
如果先前尝试进行身份验证并失败,则此方法将返回最近失败的凭据。如果proposedCredential不为nil,并且在调用其
hasPassword
方法时返回YES,则证书可以直接使用。 如果proposedCredential的hasPassword
方法返回NO,则证书提供默认用户名,客户端必须提示用户输入相应的密码。
-
@property(readonly, copy) NSURLProtectionSpace *protectionSpace
调用者的保护空间;
保护空间对象提供关于认证请求的附加信息,例如主机,端口,认证领域等。 保护空间还会告诉我们认证内容是要提供用户凭据还是验证服务器提供的TLS凭证。
-
@property(readonly, retain) id<NSURLAuthenticationChallengeSender> sender
sender通常是最初接收到身份验证挑战的NSURLProtocol子类的实例。
如果您正在使用NSURLSession API,则此值是纯信息性的,因为你必须通过将常量传递给completionHandler 来应对身份验证挑战。但是,如果你使用NSURLConnection或NSURLDownload API,则在身份验证处理委托方法中,你可以在完成处理身份验证挑战后,通过调用此sender上的NSURLAuthenticationChallengeSender协议中定义的方法来应对身份验证挑战。
参考
Overriding TLS Chain Validation Correctly
Appendix A: Common Server Trust Evaluation Errors
iOS安全系列之一:HTTPS
iOS安全系列之二:HTTPS进阶
iOS 中对 HTTPS 证书链的验证
bang:AFNetworking2.0源码解析<三>