web-dev-qa-db-fra.com

Swift 2 - Xcode 7.0 ne peut pas accéder au site HTTPS avec un certificat SSL non approuvé

Experts, je commence le IOS 9/XCODE 7/Swift 2 Development Kit 

J'essaie de créer une application ios qui achemine simplement vers une application Web en protocole HTTPS. Vous trouverez ci-dessous mon code dans ViewController.Swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet var myWebView: UIWebView!

    /**
     * Function to Display the Web Application initial URL
     */
    func loadAppURL(){
        let siteAddress = "https://domain:8443/path/to/page"
        let url = NSURL (string: siteAddress)
        let urlRequest = NSURLRequest(URL: url!)
        myWebView.loadRequest(urlRequest)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        loadAppURL()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Pendant la construction de mon application, le message d'erreur ci-dessous s'affiche. 

2015-10-01 01: 05: 13.879 Testeur de page Web [2947: 31838] NSURLSession/NSURLConnection Le chargement HTTP a échoué (kCFStreamErrorDomainSSL, -9807)

et si j'essaie de construire mon application au lieu de " https: // domaine: 8443/chemin/à/page " avec " http://www.Apple.com ", il fonctionne bien.

Je peux accéder à mon application Web dans Safari et celle-ci demande d'accepter les risques de sécurité. et je l'accepte et je peux accéder à mon application.

Guidez-moi pour résoudre mes problèmes, Merci d'avance.

10
Navas Basheer

Enfin je l'ai réparé

Xcode rejettera par défaut les certificats auto-signés non approuvés des serveurs. 

nous pouvons remplacer this Using Using NSURLConnection et communiquer avec un serveur auto-signé, car nous avons la possibilité de contrôler l'authentification via les méthodes de délégation supplémentaires qui ne sont pas disponibles pour UIWebView. Donc, en utilisant connection:didReceiveAuthenticationChallenge, nous pouvons nous authentifier auprès du serveur auto-signé. 

Références NSURLAuthenticationChallenge Docs , @Lilo Lu's Question

J'ai résolu mon problème en plusieurs étapes 
Étape 1: Définit une NSURLConnection dans la méthode viewDidLoad() de mon viewController.Swift comme suit

 override func viewDidLoad() {
    super.viewDidLoad()

    let siteAddress = "https://domain:8443/path/to/page"
    let url = NSURL (string: siteAddress)
    let urlRequest = NSURLRequest(URL: url!)
    let urlConnection:NSURLConnection = NSURLConnection(request: request, delegate: self)!
    myWebView.loadRequest(urlRequest)
 }

Étape 2: a utilisé les méthodes de délégation NSURLConnection. 

    func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool{
        print("canAuthenticateAgainstProtectionSpace method Returning True")
        return true
    }


    func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge){

        print("did autherntcationchallenge = \(challenge.protectionSpace.authenticationMethod)")

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust  {
            print("send credential Server Trust")
            let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
            challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)

        }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic{
            print("send credential HTTP Basic")
            let defaultCredentials: NSURLCredential = NSURLCredential(user: "username", password: "password", persistence:NSURLCredentialPersistence.ForSession)
            challenge.sender!.useCredential(defaultCredentials, forAuthenticationChallenge: challenge)

        }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{
            print("send credential NTLM")

        } else{
            challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
      }
}

et ça a marché !!

8
Navas Basheer

Vous pouvez ajouter ce qui suit à votre plist

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

 enter image description here

4
Mika

Dans Swift 3.

Étape 1. Ajoutez NSURLConnectionDelegate à votre contrôleur de vue pour écraser les méthodes.

class ViewController: UIViewController, NSURLConnectionDelegate {

Étape 2. Remplacez viewDidLoad

override func viewDidLoad() {
        super.viewDidLoad()

        let siteAddress = "https://mysiteaddress"
        let url = URL(string: siteAddress)
        let urlRequest = URLRequest(url: url!)
        let urlConnection:NSURLConnection = NSURLConnection(request: urlRequest, delegate: self)!
        webView.loadRequest(urlRequest)
    }

Étape 3 Écraser canAuthenticateAgainstProtectionSpace et didReceive challenge

func connection(_ connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: URLProtectionSpace) -> Bool {
    print("\ncanAuthenticateAgainstProtectionSpace method Returning True\n")
    return true
}

func connection(_ connection: NSURLConnection, didReceive challenge: URLAuthenticationChallenge) {
    print("did autherntcationchallenge = \(challenge.protectionSpace.authenticationMethod)")

    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust  {
        print("\nsend credential Server Trust\n")
        let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
        challenge.sender!.use(credential, for: challenge)

    }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic{
        print("send credential HTTP Basic")
        let defaultCredentials: URLCredential = URLCredential(user: "user", password: "password", persistence:URLCredential.Persistence.forSession)
        challenge.sender!.use(defaultCredentials, for: challenge)

    }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{
        print("\nsend credential NTLM\n")

    } else{
        challenge.sender!.performDefaultHandling!(for: challenge)
    }

}

Merci Navas Basheer pour la solution originale! M'a sauvé une tonne de temps

2
plgelso

1- Créez la catégorie "NSURLRequestCategory" -> après avoir importé cette catégorie dans votre fichier de pont créé par xcode (n'oubliez pas de laisser xCode en créer un si vous ne l'avez pas déjà fait) et mettez ce code:

    @implementation NSURLRequest (NSURLRequestCategory)

+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)Host
{
    return YES;
}
@end

Créez votre demande de chargement UIWebView normalement: 

webView.delegate = self
let myURL = URL(string: Constants.URL_DOMAINE)
let request = URLRequest(url: myURL!)
webView.loadRequest(request)

Enjoyyy: D

0
Badre