web-dev-qa-db-fra.com

Comment se connecter à des serveurs auto-signés avec Alamofire 1.3

J'obtiens l'erreur ci-dessous lors de la connexion au serveur auto-signé. 

Error Domain = NSURLErrorDomain Code = -1202 "Le certificat de ce serveur n'est pas valide. Vous vous connectez peut-être à un serveur prétendant être" maskeddomain.com ", ce qui pourrait compromettre vos informations confidentielles." UserOlfo = 0x7fb6dec259e

On dirait qu'Alamofire 1.3 ( https://github.com/Alamofire/Alamofire#security ) permet de désactiver cette validation. Quelqu'un at-il mis en œuvre cela? J'utilise les API d'Alamofire sur mon projet Swift, je ne sais pas exactement où "Server Trust Policy Manager" doit être implémenté. S'il vous plaît des conseils.

15
Arasan Rajendren

Il existe un moyen de modifier la règle de confiance du serveur de l'instance partagée du gestionnaire Alamofire, mais cela n'est pas recommandé. Au lieu de cela, vous devez créer votre propre instance personnalisée du gestionnaire. Voici la solution recommandée, le code est Swift 2.0 avec Alamofire de la branche Swift-2.0, compilé dans Xcode7 beta 5.

Création d'une instance personnalisée du gestionnaire

Étant donné que vous n'utiliserez pas la méthode request sur l'Alamofire, mais que vous utiliserez celle de votre gestionnaire personnalisé, vous devez penser à l'emplacement de stockage du gestionnaire. Ce que je fais est de le stocker en tant que statique dans mon wrapper de réseau (la classe qui utilise Alamofire et traite les besoins de mise en réseau de mes applications). Je l'installe comme ceci:

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
    }()

La prochaine étape consiste à permuter tous vos appels qui utilisent Alamofire.request() avec Manager.request(). Vous devriez donc avoir quelque chose comme:

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
            }
    })

Si vous voulez quand même changer l'instance partagée du gestionnaire, allez ici pour plus d'informations.

21
lawicko

Configuration du gestionnaire pour Swift 3 ou Swift 4 et 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
}()
34
jonaszmclaren

Un exemple est affiché directement dans le fichier README et montre comment désactiver l'évaluation si vous en avez besoin.

Étant donné que vous allez également avoir besoin de créer votre propre instance Manager, vous souhaiterez procéder de la manière suivante:

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)
        )
    }()
}

Cela vous permettra ensuite de faire des requêtes avec l'objet NetworkManager.sharedInstance.defaultManager.

12
cnoon

Une autre approche pour mon projet. La ServerTrustPolicyManager est une classe open et sa fonction serverTrustPolicy est également open. Donc, cela peut être annulé.

// 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.
    }
}

Ensuite, 

    let trustPolicies = MyServerTrustPolicyManager(policies: [:])
    let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)

UPDATE @ 2018,01

Afin de déclencher la ServerTrustPolicyManager, le Info.plist du projet doit être configuré. J'ai trouvé la solution, détail à ce post, le commentaire de cnoon @ 01 Nov 2015 .

 enter image description here

Par exemple, s'il existe des URL nommées site1.foo.com, site2.foo.com, .....__, ajoutez ensuite le dictionnaire App Transport Security Settings -> Exception Domains -> foo.com, avec les entrées suivantes.

  • NSExceptionRequiresForwardSecrecy: NO
  • NSExceptionAllowsInsecureHTTPLoads: OUI
  • NSIncludesSubdomains: YES

Plus de détails vous pouvez vous référer à la poste.

3
AechoLiu

Quoi qu'il en soit, la réponse de @cnoon est presque complète. Mais j'ai rencontré un autre problème de validation SSL, je veux donc mettre mon code ici si quelqu'un peut obtenir de l'aide. Le gestionnaire 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))

Ensuite, utilisez le gestionnaire pour demander:

// 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 .: c'est l'échantillon de Swift 2.3

1
Raniys