English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Summary: At WWDC 2016at the Apple Developer Conference, Apple announced a deadline: by2017Year1Month1Day, all applications in the App Store must enable App Transport Security (ATS) security feature. App Transport Security (ATS) is a privacy protection feature introduced by Apple in iOS 9is a privacy protection feature introduced, which blocks the loading of plaintext HTTP resources, and the connection must be through more secure HTTPS. Apple currently allows developers to temporarily disable ATS and continue to use HTTP connections, but all official store applications must be mandatory to use ATS by the end of the year.
The framework used in the project is AFNetworking 3.0 and above versions, due to ATS reasons, iOS only allows the use of links starting with Https, in2016Year12Month3Before 0th, Apple allowed to bypass ATS, as shown in the figure below:
However, from2017Year1Month1Starting from this date, Apple will no longer accept applications using http to load resources, so this article mainly explains how to use AFN to authenticate self-signed certificates (Note: For certificates certified by CA institutions, no authentication is required; you can directly use links starting with Https for data access and page loading). The project has been uploaded to GitHub (if you need to refer to the source code, please click the link):HttpsSignatureCertificate_jb51.rar
1,establish a root class named AKNetPackegeAFN
1> .h file, create the necessary Get and Post methods
#import <Foundation/Foundation.h> typedef enum{ AKNetWorkGET , /**< GET request */ AKNetWorkPOST = 1 /**< POST request */ }AKNetWorkType; typedef void (^HttpSuccess)(id json); typedef void (^HttpErro)(NSError* error); @interface AKNetPackegeAFN : NSObject +(instancetype)shareHttpManager; /* * netWorkType:Request method GET or POST signature:Whether to use a signature certificate, if yes, write the certificate name directly, if no, fill nil api:Request URL interface parameters:Request parameters sucess:Return value when request succeeds fail:Return value when request fails * */ - (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail; @end
2> .m file, import header file AFNetworking.h, create a Manager property, and implement the shareHttpManager class method
#import "AKNetPackegeAFN.h" #import "AFNetworking.h" @interface AKNetPackegeAFN() @property (nonatomic,strong) AFHTTPSessionManager *manager; @end @implementation AKNetPackegeAFN +(instancetype)shareHttpManager{ static dispatch_once_t onece = 0; static AKNetPackegeAFN *httpManager = nil; dispatch_once(&onece, ^(void){ httpManager = [[self alloc]init]; }); return httpManager; }
2, Implementation of Get and Post methods
When using, convert the certificate provided by the background to .cer format, drag it into the root directory of the project, and bind it in the method. For example, the name of the certificate provided by the background is: Kuture.crt After receiving the certificate, double-click to install it, then open the Keychain, right-click on the certificate named Kuture to export it, select the suffix as .cer, and then confirm as shown in the following figure:
--> -->
-->
Encapsulation of GET and POST implementation methods
- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail{ //Enable certificate verification mode AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; //Whether to allow the use of self-signed certificates signature == nil ? (void)(securityPolicy.allowInvalidCertificates = NO):(securityPolicy.allowInvalidCertificates = YES); //Whether to validate the domain name securityPolicy.validatesDomainName = NO; _manager = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:api]]; _manager.responseSerializer = [AFJSONResponseSerializer serializer]; _manager.securityPolicy = securityPolicy; _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"application/xml",@"text/xml",@"text/json",@"text/plain",@"text/javascript",@"text/html", nil]; if (signature != nil){ __weak typeof(self) weakSelf = self; [_manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *_credential) { //Obtain the server's trust object SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; //Import self-signed certificate NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"Your Certificate Name" ofType:@"cer"]; NSData *cerData = [NSData dataWithContentsOfFile:cerPath]; if (!cerData) { NSLog(@"==== .cer file is nil ===="); return 0; } NSArray *cerArray = @[cerData]; weakSelf.manager.securityPolicy.pinnedCertificates = cerArray; SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cerData); NSCAssert(caRef != nil, @"caRef is nil"); NSArray *caArray = @[(__bridge id)(caRef)]; NSCAssert(caArray != nil, @"caArray is nil"); //Set the read certificate as the root certificate of serverTrust OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray); SecTrustSetAnchorCertificatesOnly(serverTrust, NO); NSCAssert(errSecSuccess == status, @"SectrustSetAnchorCertificates failed"); //Select the handling method for the challenge authentication NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __autoreleasing NSURLCredential *credential = nil; //NSURLAuthenticationMethodServerTrust challenge authentication method if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { //Decide whether to trust the server based on the client's security policy, and do not respond to the challenge if it is not trusted if ([weakSelf.manager.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { //Create the challenge credential credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; //Confirm the challenge method if (credential) { disposition = NSURLSessionAuthChallengeUseCredential; disposition = NSURLSessionAuthChallengePerformDefaultHandling; return disposition; } disposition = NSURLSessionAuthChallengePerformDefaultHandling; //Cancel the challenge } } disposition = NSURLSessionAuthChallengePerformDefaultHandling; return disposition; } if (netWorkType == 0){ } } [_manager GET:api parameters:parameters progress:^(NSProgress else if (netWorkType == * _Nonnull uploadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if (sucess){ sucess(responseObject); } failure:^(NSURLSessionDataTask } } * _Nullable task, NSError * _Nonnull error) { fail(error); } } 1){ [_manager POST:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if (sucess){ sucess(responseObject); } failure:^(NSURLSessionDataTask } } * _Nullable task, NSError * _Nonnull error) { fail(error); } } }
2 Usage, directly import the header file AKNetPackegeAFN.h in the class where data acquisition or transmission is required, and implement the method, as shown below:
//Create an object //If it is a self-signed certificate, bind the certificate to the corresponding method of AKNetPackegeAFN before use (the certificate can be directly dragged into the project). /* * netWorkType:Request method GET or POST signature:Whether to use a signature certificate, if yes, write the certificate name directly, if no, fill nil api:Request URL interface parameters:Request parameters sucess:Return value when request succeeds fail:Return value when request fails * */ AKNetPackegeAFN *netHttps = [AKNetPackegeAFN shareHttpManager]; [netHttps netWorkType:Request Type Signature:Certificate Name API:Request URL Parameters:Parameters Success:^(id json) { NSLog(@"Json:%@",json); } *error) { NSLog(@"Error:%@",error); }
That's all for this article. Hope it will be helpful to your learning and also hope that everyone will support the Yelling Tutorial.
Declaration: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#w3Please report via email to codebox.com (replace # with @ when sending an email) and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.