I am trying to figure out how to use Alamofire 4.0 with Swift 3.0 to send a p12 (i also have the PEM cert and key if need be) to a website for authentication. All the exam
Here is my example that might help someone (Alamofire 4.0, Swift 3, xCode 8)
import Alamofire
class NetworkConnection {
let developmentDomain = Config.developmentDomain // "api.myappdev.com"
let productionDomain = Config.productionDomain // "api.myappprod.com"
let certificateFilename = Config.certificateFilename // "godaddy"
let certificateExtension = Config.certificateExtension // "der"
let useSSL = true
var manager: SessionManager!
var serverTrustPolicies: [String : ServerTrustPolicy] = [String:ServerTrustPolicy]()
static let sharedManager = NetworkConnection()
init(){
if useSSL {
manager = initSafeManager()
} else {
manager = initUnsafeManager()
}
}
//USED FOR SITES WITH CERTIFICATE, OTHERWISE .DisableEvaluation
func initSafeManager() -> SessionManager {
setServerTrustPolicies()
manager = SessionManager(configuration: URLSessionConfiguration.default, delegate: SessionDelegate(), serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
return manager
}
//USED FOR SITES WITHOUT CERTIFICATE, DOESN'T CHECK FOR CERTIFICATE
func initUnsafeManager() -> SessionManager {
manager = Alamofire.SessionManager.default
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) //URLCredential(forTrust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = self.manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
return manager
}
func setServerTrustPolicies() {
let pathToCert = Bundle.main.path(forResource: certificateFilename, ofType: certificateExtension)
let localCertificate:Data = try! Data(contentsOf: URL(fileURLWithPath: pathToCert!))
let serverTrustPolicies: [String: ServerTrustPolicy] = [
productionDomain: .pinCertificates(
certificates: [SecCertificateCreateWithData(nil, localCertificate as CFData)!],
validateCertificateChain: true,
validateHost: true
),
developmentDomain: .disableEvaluation
]
self.serverTrustPolicies = serverTrustPolicies
}
static func addAuthorizationHeader (_ token: String, tokenType: String) -> [String : String] {
let headers = [
"Authorization": tokenType + " " + token
]
return headers
}
}
add following to your Info.plist
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSExceptionDomains
api.myappdev.com
NSExceptionAllowsInsecureHTTPLoads
NSExceptionRequiresForwardSecrecy
NSIncludesSubdomains
NSRequiresCertificateTransparency
NSTemporaryExceptionMinimumTLSVersion
TLSv1.2
and here is an example of making an request
import Alamofire
class ActionUserUpdate {
let url = "https://api.myappdev.com/v1/"
let manager = NetworkConnection.sharedManager.manager
func updateUser(_ token: String, tokenType: String, expiresIn: Int, params: [String : String]) {
let headers = NetworkConnection.addAuthorizationHeader(token, tokenType: tokenType)
manager?.request(url, method: .put, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
print(response.description)
print(response.debugDescription)
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
}
}
}