How to use Alamofires ServerTrustPolicy.disableEvaluation in swift 3
Try this which seems to be working for me -
extension SessionManager {
static func getManager() -> SessionManager{
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"192.168.1.28:8443": .disableEvaluation
]
let configuration = Reqres.defaultSessionConfiguration()
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
return Alamofire.SessionManager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}
}
And to use this SessionManager do the following -
var manager: SessionManager?
manager = SessionManager.getManager()
manager?.request// Here is your request call.
How to use Alamofires ServerTrustPolicy.disableEvaluation in swift 5 alamofire 5.0.3
ServerTrustPolicy
has been replaced with the protocol ServerTrustEvaluating
in Alamofire 5, and DisabledEvaluator
has replaced the .disabled
enum case. To replicate the custom setup you had before:
private let session: Session = {
let manager = ServerTrustManager(evaluators: ["serverurl.com": DisabledEvaluator()])
let configuration = URLSessionConfiguration.af.default
return Session(configuration: configuration, serverTrustManager: manager)
}()
Alamofire - Use of undeclared type 'ServerTrustPolicy'?
Yes, it appears that Alamofire has changed this, so the documentation seems to be out of date:
The previous ServerTrustPolicy enum has be refactored into classes which implement ServerTrustEvaluating
Reference: https://github.com/Alamofire/Alamofire/pull/2344
Your solution will be dependent on which version of Alamofire you are using. Certainly this would not impact you in versions 4.6.0 or below, so it seems you are using a newer version.
In the latest master branch (representing 5.0.0-beta7 release), it seems the equivalent code you are looking for is the evaluators
property on ServerTrustManager
, and you can use the provided DefaultTrustEvaluator
class for the ServerTrustEvaluating
objects. There are several other evaluators in the same file if you require advanced usage.
Related source files: https://github.com/Alamofire/Alamofire/blob/master/Source/ServerTrustEvaluation.swift
How to connect to self signed servers using Alamofire 1.3
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.
Change serverTrustPolicy of Alamofire.SessionManager to still use top-level convenience methods like Alamofire.request
Just create class and call it "NetManager" with static var of type SessionManager in it.
class NetManager {
static var manager : SessionManager = {
// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"my server url": .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
}()
}
Then use it like this:
NetManager.manager
.request(MyRouter.login())
.responseJSON { response in
//
}
Alamofire without evaluation and with sending client certificate
Problem self solved.
now the answer for SENDING CLIENT SIDE CERTIFICATE maybe someone will need it :)
We need PKCS12 to send certificate so
import Foundation
public class PKCS12 {
let label:String?
let keyID:NSData?
let trust:SecTrust?
let certChain:[SecTrust]?
let identity:SecIdentity?
public init(PKCS12Data:NSData,password:String)
{
let importPasswordOption:NSDictionary = [kSecImportExportPassphrase as NSString:password]
var items : CFArray?
let secError:OSStatus = SecPKCS12Import(PKCS12Data, importPasswordOption, &items)
guard secError == errSecSuccess else {
if secError == errSecAuthFailed {
NSLog("ERROR: SecPKCS12Import returned errSecAuthFailed. Incorrect password?")
}
fatalError("SecPKCS12Import returned an error trying to import PKCS12 data")
}
guard let theItemsCFArray = items else { fatalError() }
let theItemsNSArray:NSArray = theItemsCFArray as NSArray
guard let dictArray = theItemsNSArray as? [[String:AnyObject]] else { fatalError() }
func f<T>(key:CFString) -> T? {
for d in dictArray {
if let v = d[key as String] as? T {
return v
}
}
return nil
}
self.label = f(key: kSecImportItemLabel)
self.keyID = f(key: kSecImportItemKeyID)
self.trust = f(key: kSecImportItemTrust)
self.certChain = f(key: kSecImportItemCertChain)
self.identity = f(key: kSecImportItemIdentity)
}
}
extension URLCredential {
public convenience init?(PKCS12 thePKCS12:PKCS12) {
if let identity = thePKCS12.identity {
self.init(
identity: identity,
certificates: thePKCS12.certChain,
persistence: URLCredential.Persistence.forSession)
}
else { return nil }
}
}
we need x509 also to do PKCS12 I was in need of generating certificates dynamically so theres the code bridged from C
-(void) createX509{
OPENSSL_init();
NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/cert"];
NSString *docPathKey = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/key"];
NSString *docPathp12 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/p12"];
NSString *dataFile = [NSString stringWithContentsOfFile:docPath
encoding:NSUTF8StringEncoding
error:NULL];
FILE *fp = fopen(docPath.UTF8String, "r");
if(fp == NULL){
fp = fopen(docPath.UTF8String, "w+");
FILE *fpKey = fopen(docPathKey.UTF8String, "w+");
EVP_PKEY * pkey;
pkey = EVP_PKEY_new();
RSA * rsa;
rsa = RSA_generate_key(
2048, /* number of bits for the key - 2048 is a sensible value */
RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
NULL, /* callback - can be NULL if we aren't displaying progress */
NULL /* callback argument - not needed in this case */
);
EVP_PKEY_assign_RSA(pkey, rsa);
X509 * x509;
x509 = X509_new();
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000000L);
X509_set_pubkey(x509, pkey);
X509_NAME * name;
name = X509_get_subject_name(x509);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
(unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
(unsigned char *)"company", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
(unsigned char *)"localhost", -1, -1, 0);
X509_set_issuer_name(x509, name);
X509_sign(x509, pkey, EVP_sha1());
[@"" writeToFile:docPath
atomically:YES
encoding:NSUTF8StringEncoding
error:NULL];
fp = fopen(docPath.UTF8String, "a+");
PEM_write_X509(
fp, /* write the certificate to the file we've opened */
x509 /* our certificate */);
PEM_write_PrivateKey(fpKey, pkey, NULL, NULL, 0, NULL, NULL);
fflush(fpKey);
fclose(fpKey);
fflush(fp);
fclose(fp);
dataFile = [NSString stringWithContentsOfFile:docPath
encoding:NSUTF8StringEncoding
error:NULL];
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
PKCS12* p12;
p12 = PKCS12_create("password", "login", pkey, x509, NULL, 0,0,0,0,0);
if(!p12) {
fprintf(stderr, "Error creating PKCS#12 structure\n");
ERR_print_errors_fp(stderr);
exit(1);
}
fp = fopen(docPathp12.UTF8String, "w+");
if (!(fp = fopen(docPathp12.UTF8String, "wb"))) {
ERR_print_errors_fp(stderr);
exit(1);
}
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fflush(fp);
fclose(fp);
}
The pkcs12 and x05 is now made so we continue in swift
public let alamofireManager: SessionManager = {
let obj = OpenSSL();
obj.createX509()
var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first;
var certPEM:String!;
var keyPEM:String!;
var certificateToPin:SecCertificate!;
var pkcs12:PKCS12?;
do{
try certPEM = String(contentsOfFile: path! + "/cert").replacingOccurrences(of: "\n", with: "")
try keyPEM = String(contentsOfFile: path! + "/key").replacingOccurrences(of: "\n", with: "")
let p12 = NSData(contentsOfFile: path! + "/p12");
pkcs12 = PKCS12.init(PKCS12Data: p12!, password: "password")
let docsurl = try! FileManager.default.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let urlAp = docsurl.appendingPathComponent("cert");
var cert64 = certPEM.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "")
cert64 = cert64.replacingOccurrences(of: "-----END CERTIFICATE-----", with: "")
let certificateData = NSData(base64Encoded: cert64, options: .ignoreUnknownCharacters)
certificateToPin = SecCertificateCreateWithData(kCFAllocatorMalloc, certificateData!)
var trust: SecTrust?
let policy = SecPolicyCreateBasicX509()
let status = SecTrustCreateWithCertificates(certificateToPin!, policy, &trust)
let publicKey:SecKey?;
if status == errSecSuccess {
publicKey = SecTrustCopyPublicKey(trust!)!;
}
let dictionary = SecPolicyCopyProperties(policy)
}catch{
print("err")
}
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForResource = Request.settings.timeout
let trustPolicies = CertTrustPolicyManager(policies: [:])
var serverTrustPolicy:[String: ServerTrustPolicy] = [
Router.baseURLString : .pinCertificates(
certificates: [certificateToPin],
validateCertificateChain: false,
validateHost: false)
]
var alamofireManager:SessionManager = Alamofire.SessionManager(configuration: configuration, delegate: SessionDelegate(), serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicy))
alamofireManager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .useCredential
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = alamofireManager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
let certs = [certificateToPin]
let persist = URLCredential.Persistence.forSession;
return (disposition, URLCredential.init(PKCS12: pkcs12!))
}
return alamofireManager
}()
There I was in need to get certificates, probably some of code is useless or badly wrote but its working ( I'm new to IOS :) ), I was also converting PEM certificates to DER there but after these operations I was finally able to do insecure connection with sending client side and created certificate with Alamofire.
The code above is gathered from everywhere!
Cheers
Related Topics
Operation Went Isfinished=Yes Without Being Started by the Queue It Is In
Swift Bridging Header File Won't Work with Use_Frameworks
How to Work with Udp Sockets in iOS, Swift
What Is a Safe Way to Turn Streamed (Utf8) Data into a String
Delete Image from Photo Gallery
How to Update iOS 14 Widget Background Color from the App
How to Draw a Simple Rounded Rect in Swift (Rounded Corners)
How to Add Followed Text to Uitextfield
Swift - Uitableview Didselectrowatindexpath & Diddeselectrowatindexpath Add & Remove Indexpath Ids
How to Add the Same Background Image to All Views in My iOS App Using Swift
Dyld: Symbol Not Found: _Tmpdcss12Anygenerator
Outline Uilabel Text in Uilabel Subclass
Custom Mkoverlayrenderer Drawmaprect Function Not Drawing Polygons
Swift: Triggering Tableviewcell to Lead to a Link in a Uiwebview in Another Viewcontroller
iOS - Setobject VS. Synchronize
Swift 3 - Passing Data Between a View Controller and After That to Another 2