I get the below error while connecting to self signed server.
Error Domain=NSURLErrorDomain Code=-1202 \"The certificate for this server is invalid. You might be co
Another approach for my project. The ServerTrustPolicyManager
is an open
class, and it's serverTrustPolicy
function is open
too. So it can be override.
// For Swift 3 and Alamofire 4.0
open class MyServerTrustPolicyManager: ServerTrustPolicyManager {
// Override this function in order to trust any self-signed https
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return ServerTrustPolicy.disableEvaluation
// or, if `host` contains substring, return `disableEvaluation`
// Ex: host contains `my_company.com`, then trust it.
}
}
Then,
let trustPolicies = MyServerTrustPolicyManager(policies: [:])
let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)
In order to trigger the ServerTrustPolicyManager
, the project's Info.plist
needs to be configured. I found the solution, detail at this post, cnoon's comment @ 1 Nov 2015.
For example, if there are urls named site1.foo.com
, site2.foo.com
, ....
Then add App Transport Security Settings
-> Exception Domains
-> foo.com
dictionary, with following entries.
More detail you can refer the post.
An example is posted right in the README demonstrating exactly how to disable evaluation if you need to do so.
Since you are going to need to create your own Manager
instance as well, you'll want to do something like the following:
class NetworkManager {
static let sharedInstance = NetworkManager()
let defaultManager: Alamofire.Manager = {
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"test.example.com": .PinCertificates(
certificates: ServerTrustPolicy.certificatesInBundle(),
validateCertificateChain: true,
validateHost: true
),
"insecure.expired-apis.com": .DisableEvaluation
]
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
return Alamofire.Manager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}()
}
This will then allow you to make requests with the NetworkManager.sharedInstance.defaultManager
object.
Manager configuration for Swift 3 or Swift 4 and Alamofire 4:
private static var manager: Alamofire.SessionManager = {
// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"test.example.com": .disableEvaluation
]
// Create custom manager
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
let manager = Alamofire.SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
return manager
}()
Anyway, the answer of @cnoon almost full. But I met another trouble of the ssl validation, so I want to put my code here if someone can get help from it.The manager init as:
private var manager: Manager?
// Import the certificates like xxx.cer to your project(anywhere will be fine), then the ServerTrustPolicy.certificatesInBundle() can find them
let serverTrustPolicy = ServerTrustPolicy.PinCertificates(
certificates: ServerTrustPolicy.certificatesInBundle(),
validateCertificateChain: false,
validateHost: true
)
let serverTrustPolicies: [String : ServerTrustPolicy] = [
"sub.server.com": .DisableEvaluation, // because the certificates only add the main domain, so disable evaluation for subdomain
"192.168.0.2:8090": .DisableEvaluation, // the IP address for request data
"www.server.com": serverTrustPolicy
]
manager = Manager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
Then use the manager to request:
// this function in the class which for manager the Alamofire request
public func request(method: Alamofire.Method, _ URLString: URLStringConvertible,
parameters: [String : AnyObject]?) -> Alamofire.Request
{
// we do not need use Alamofire.request now, just use the manager you have initialized
return manager!.request(method, URLString, parameters: parameters,
headers: ["tokenId": UserManager_Inst.tokenID])
}
p.s.: it is the swift 2.3 sample
There is a way to change the Server Trust Policy of the Alamofire manager shared instance, but it's not recommended. Instead you should create your own customised instance of the manager. Here is the recommended solution, code is Swift 2.0 with Alamofire from swift-2.0 branch, compiled in Xcode7 beta 5.
Creating customised instance of the manager
Because you will not use the request method on the Alamofire, but use the one on your custom manager instead, you need to think of where to store the manager. What I do is to store it as static in my networking wrapper (the class that utilizes Alamofire and deals with my application networking needs). I set it up like this:
private static var Manager : Alamofire.Manager = {
// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"maskeddomain.com": .DisableEvaluation
]
// Create custom manager
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
let man = Alamofire.Manager(
configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
return man
}()
Next step is to switch all your calls that use Alamofire.request()
with Manager.request()
, so you should have something like this:
Manager.request(.GET, "http://stackoverflow.com").responseJSON(
completionHandler: { (_, respose, result) -> Void in
if result.isSuccess {
// enjoy your success
} else if result.isFailure {
// deal with your failure
}
})
If you want to change the shared instance of the manager anyway, go here for more info.