个NSURLProtectionSpace提供如下信息:
//401的认证方式的realm字段的值
(NSString*)realm;
//401的认证方式,指定是否密码发送安全。
-(BOOL)receivesCredentialSecurely;
//代理授权
-(BOOL)isProxy;
//服务端主机地址,如果是代理则代理服务器地址
-(NSString *)host;
//服务端端口地址,如果是代理则代理服务器的端口
-(NSInteger)port;
//代理类型,只对代理授权,比如http代理,socket代理等。
-(NSString *)proxyType;
//使用的协议,比如http,https, ftp等,
-(NSString *)protocol;
//最关键字段,指定授权方式,比如401,客户端认证,服务端信任,代理等。
-(NSString *)authenticationMethod;
//客户端认证,是指定可接受的客户端证书列表??表示只有这些证书才可以??
-(NSArray *)distinguishedNames NS_AVAILABLE(10_6,3_0);
//用于服务端信任,指定一个信任对象,可以用这个对象来建立一个凭证。
-(SecTrustRef)serverTrust NS_AVAILABLE(10_6,3_0);
保护空间的建立提供2个方法:
(id)initWithHost:(NSString*)host port:(NSInteger)port protocol:(NSString *)protocolrealm:(NSString *)realm authenticationMethod:(NSString*)authenticationMethod;
//代理的保护空间
-(id)initWithProxyHost:(NSString*)host port:(NSInteger)port type:(NSString *)type realm:(NSString*)realm authenticationMethod:(NSString *)authenticationMethod;
好了有了保护空间类,也凭证类我们就可以把信息从凭证空间读取或者保存了,凭证空间提供了如下的方法:
//根据保护空间得到凭证对象字典,这个字典的key是用户名,而value是NSURLCredential
-(NSDictionary *)credentialsForProtectionSpace:(NSURLProtectionSpace*)space;
//所有凭证对象字典,key是保护空间,value是一个字典,其中value的key是用户名字,value是凭证
-(NSDictionary *)allCredentials;
//保存凭证
-(void)setCredential:(NSURLCredential*)credential forProtectionSpace:(NSURLProtectionSpace *)space;
//删除凭证
-(void)removeCredential:(NSURLCredential*)credential forProtectionSpace:(NSURLProtectionSpace *)space;
//设置某个保护空间的默认凭证
-(NSURLCredential*)defaultCredentialForProtectionSpace:(NSURLProtectionSpace *)space;
//获取某个凭证空间的默认凭证
-(void)setDefaultCredential:(NSURLCredential*)credential forProtectionSpace:(NSURLProtectionSpace *)space;
当我们的凭证存储空间有变化时会发送FOUNDATION_EXPORTNSString *constNSURLCredentialStorageChangedNotification;通知。
好了说了这么多,然我们来继续看看挑战类吧NSURLAuthenticationChallenge,一个挑战类会包含:保护空间信息,凭证类(如果有的话),
我们再来捋顺一下逻辑,当我们发送请求到服务端时,服务端需要我们挑战时会在客户端创建一个挑战对象NSURLAuthenticationChallenge,其中的保护空间NSURLProtectionSpace由服务器响应的信息来构建,而<NSURLAuthenticationChallengeSender>sender则内部构建,然后挑战对象会根据保护空间从凭证存储中获取对应的凭证对象,如果有凭证对象则会把凭证对象赋值给数据成员proposedCredential,建立挑战对象后判断当前有没有实现NSURLConnection的willSendRequestForAuthenticationChallenge的函数,如果没有实现则根据凭证对象来调用sender的接受挑战或者失败函数,而如果是我们实现了willSendRequestForAuthenticationChallenge就需要我们自己来处理如何接收挑战了,注意当我们调用sender的接收挑战函数,这个函数内部会把凭证和保护空间保存到凭证存储中去,以便下次继续使用(当然可以通过控制凭证的持久属性来决定是否保存)。因此有的时候我们可以在系统中预先植入一些特定服务器的保护空间和凭证,这样我们就不需要去处理willSendRequestForAuthenticationChallenge函数了,这种机制特别有效的用于处理webview来访问有些需要授权的或者https或者代理等等。
http://blog.csdn.net/antjumper/article/details/51567945