Swift和Alamofire SSL固定和处理挑战

时间:2017-05-23 14:03:10

标签: json swift alamofire challenge-response

当我尝试从内部Web服务器获取json时,我需要处理这个挑战。我跟上前一个问题的this。这是我的代码

let defaultManager: Alamofire.SessionManager = {
            let serverTrustPolicies: [String: ServerTrustPolicy] = [
                "myhttpsinternaldomain.org": .disableEvaluation
            ]

            let configuration = URLSessionConfiguration.default
            configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders

            return Alamofire.SessionManager(
                configuration: configuration,
                serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
            )
        }()

        let url = URL(string: urlString)
        let username = "user"
        let password = "password"
        let header = ["user": username, "password": password]

        defaultManager.request(url!, method: .get, headers: header).responseJSON { response in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
                print("JSON: \(json)")
            case .failure(let error):
                print(error)
            }
        }

这是我收到的错误

  

错误域= NSURLErrorDomain代码= -999"已取消" UserInfo = {NSErrorFailingURLKey = https://myhttpsinternaldomain.org,NSLocalizedDescription =已取消,NSErrorFailingURLStringKey = https://myhttpsinternaldomain.org}

我找到了this,但我的项目中没有令牌。我想只使用用户名和密码或忽略挑战

请任何帮助

2 个答案:

答案 0 :(得分:2)

知道了!或者说我找到了正确的页面,这让我得到了答案。 Github Page Server Trust Policy Managerconnect to self signed servers using Alamofire

最初我会在SSL拒绝我的身份验证后收到310错误。

然后我添加了我最初发布的经理类,并收到了一个-999错误,说它已被取消"。感谢上面的Github页面,原因是因为我需要

  

"确保保留对新SessionManager实例的引用,   否则你的请求将被取消   sessionManager已取消分配。"

所以我创建了一个NetworkManager类,这要归功于第二个stackoverflow页面,并在我的alamofire请求中调用它。

下面的代码可以使用,希望这可以节省很多时间。

// Network Manager outside view controller

        class NetworkManager {
        static let sharedInstance = NetworkManager()

        let manager: Alamofire.SessionManager = {
            let serverTrustPolicies: [String: ServerTrustPolicy] = [
                "https://mydomainthatwasdrivingmebananas.com": .pinCertificates(
                    certificates: ServerTrustPolicy.certificates(),
                    validateCertificateChain: true,
                    validateHost: true),
                "mydomainthatwasdrivingmebananas.com": .disableEvaluation
            ]

            let configuration = URLSessionConfiguration.default
            configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders

            return Alamofire.SessionManager(
                configuration: configuration,
                serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
            )
        }()
    }

然后Alamofire致电

// Inside ViewController ViewDidLoad

NetworkManager.sharedInstance.manager.request("https://mydomainthatwasdrivingmebananas.com", method: .get).responseJSON{ response in
                switch response.result {
                                case .success(let value):
                                    let json = JSON(value)
                                    print("JSON: \(json)")
                                case .failure(let error):
                                    print(error)
                                }

        }

P.S JSON()方法是一个很好的JSON,以防任何人感到困惑

答案 1 :(得分:0)

您不能像在邮递员中那样在标题中发送这样的用户名和密码。你必须将它们更改为base64。这是邮递员在将标题添加到标题时在后台执行的操作。

// Your hostname and endpoint
let hostname = "myhttpsinternaldomain.org"
let cert = "YOUR_CERT" // e.g. for cert.der, this should just be "cert"

// Set up certificates
let pathToCert = Bundle.main.path(forResource: cert, ofType: "der")
let localCertificate = NSData(contentsOfFile: pathToCert!)
let certificates = [SecCertificateCreateWithData(nil, 
localCertificate!)!]

// Configure the trust policy manager
let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
certificates: certificates,
validateCertificateChain: true,
validateHost: true
)    
let serverTrustPolicies = [hostname: serverTrustPolicy]
let serverTrustPolicyManager = ServerTrustPolicyManager(policies: 
serverTrustPolicies)

// Configure session manager with trust policy
let defaultManager = Alamofire.SessionManager(
  configuration: URLSessionConfiguration.default,
  serverTrustPolicyManager: serverTrustPolicyManager
)

let url = URL(string: urlString)

let user = "user"

let password = "password"

let base64 = "\(user):\(password)".toBase64()



   let header = [

        "Authorization": "Basic \(base64)"
   ]

   //Added encoding type in the request. Change and try other types too. Like JSONEncoding.default
    defaultManager.request(url!, method: .get, encoding: URLEncoding.default ,headers: header).responseJSON { response in
        switch response.result {
        case .success(let value):
            let json = JSON(value)
            print("JSON: \(json)")
        case .failure(let error):
            print(error)
        }
    }

extension String {

   func toBase64() -> String {
       return Data(self.utf8).base64EncodedString()
   }
}

enter image description here