This my first project using swift. I am usin alamofire to connect the API. I have a local copy form the API I want to use for debugging - so I can set test data - because the remote API has already real data that I can't mess with.
The problem is I am getting the below error when I try to access https://localhost:8443/MyProject
Optional(Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk." UserInfo=0x7fbeb8c61ff0 {NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9813, NSUnderlyingError=0x7fbeb8ea5c00 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1202.)", NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk., NSErrorFailingURLKey=https://localhost:8443/myproject/api/loginUser.pdo, NSErrorFailingURLStringKey=https://localhost:8443/myproject/api/loginUser.pdo, _kCFStreamErrorDomainKey=3})
I have found many solution most of them for Objective-c as using setAllowsAnyHTTPSCertificate
or using the delegate for Connection.
but I could not find an equevelent method for setAllowsAnyHTTPSCertificate
in swift, and I not sure how to set the delegate to the connection while using alamofire.
any ideas what I need to do?
setAllowsAnyHTTPSCertificate
is private api and will cause the project to be rejected by Apple. I want to use it only while debugging then it will be removed before the publishing the project.Thank you in advance.
You can easily override the default challenge behavior in Alamofire using the SessionDelegate
override closures. Here is an example of how you can allow Alamofire to accept invalid certificates:
IMPORTANT: Please do not use this in any production code. Security is VERY important and this implementation completely disregards the security mechanisms in Alamofire. Use at your own risk!
let manager = Alamofire.Manager.sharedInstance
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
var credential: NSURLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = NSURLSessionAuthChallengeDisposition.UseCredential
credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
} else {
if challenge.previousFailureCount > 0 {
disposition = .CancelAuthenticationChallenge
} else {
credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
if credential != nil {
disposition = .UseCredential
}
}
}
return (disposition, credential)
}
We (the Alamofire TC) are going to implement TLS pinning and several other features related to security in the Alamofire 1.3.0 release.
The Alamofire 1.3.0 release is out and adds MUCH better support for customizing server trust authentication challenges. For further info, please check out the Security section of the README.
Thank you for sharing this! Could you provide any direction for where this code may go? I'm new to iOS and learning this as I go. I am only turning this off to test my app. My production server is the only one at this point with a valid SSL cert and I REALLY do not want to test my app against production at this stage.
This blog should get you going in the right direction.
Thanks for sharing that blog. It will be very helpful but isn't really what I was asking. I'm not sure where the above code you posted is supposed to live. I've placed it in a number of places in my app but the overridden delegate method is never called.
Edit submitted but I figured out why this code was not working for me. It is creating a brand new Alamofire.Manager instance and setting the delegate method on that instance. It should set the delegate method on Alamofire.Manager.sharedInstance instead so that it properly overrides the instance being used by the framework. Thank again for sharing the code, @cnoon!
Sorry for the confusion @ShatyUT. In order to avoid this issue for others in the future, I updated the answer accordingly. This is a common mistake that I've seen many times on various Alamofire questions.