gpt4 book ai didi

ios - Alamofire 4.0 的证书无效问题

转载 作者:可可西里 更新时间:2023-11-01 04:17:02 27 4
gpt4 key购买 nike

我正在尝试通过 https 为我的 iOS 应用程序使用网络服务。 Web 服务器使用自签名证书。

使用网络服务时,出现“证书无效”错误。

FAILURE: Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “portal” which could put your confidential information at risk."

我知道最佳做法是在服务器端修复此问题以启用受信任的根 CA。但由于这是一个临时开发环境,我们使用的是自签名证书。由于这是 ATS 问题,我在我的 info.plist 中编辑了 ATS,如下所示。

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>devportal</key>
<dict>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
</plist>

由于 NSException 域不适用于 IP 和端口号,我在我的 etc/hosts 文件中为 Web 服务器 IP 创建了一个主机条目,并像 https://devportal:8443/rest/login 一样使用它。而不是将其作为 https://192.22.xx.xxx:8443/rest/login 使用

我遵循了关于服务器信任策略的 alamofire 文档,编辑了 ATS 以允许异常域,但对我来说没有任何效果。我在这个问题上花了 3 天多的时间。我错过了什么吗?有人遇到过类似的问题吗?有什么解决办法吗?提前致谢

我使用的是 almofire 4.0,Xcode 8.0。下面是我的代码。

class LoginService{
private static var Manager: Alamofire.SessionManager = {

let pathToCert = Bundle.main.path(forResource: "192.22.xx.xxx", ofType: "crt") // Downloaded this certificate and have added to my bundle
let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!

// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"192.22.xx.xxx": .pinCertificates(
certificates: [SecCertificateCreateWithData(nil, localCertificate)!],
validateCertificateChain: true,
validateHost: true
),

"devportal:8443": .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
}()



/**
Calls the Login Web Service to authenticate the user
*/
public func login(username:String, password: String){

let parameters = [
"username": "TEST",
"password": "PASSWORD",
]
let header: HTTPHeaders = ["Accept": "application/json"]
LoginService.Manager.request("https://devportal:8443/rest/login", method: .post, parameters: parameters, encoding: JSONEncoding(options: []),headers :header).responseJSON { response in
debugPrint(response)

if let json = response.result.value {
print("JSON: \(json)")
}
}



}
}

最佳答案

我像下面这样修改了我的代码并且它起作用了。我提到了Swift: How to Make Https Request Using Server SSL Certificate用于解决此问题。

       class LoginService{
private static var Manager: Alamofire.SessionManager = {

// Create the server trust policies
let serverTrustPolicies: [String: ServerTrustPolicy] = [

"devportal:8443": .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
}()



/**
Calls the Login Web Service to authenticate the user
*/
public func login(username:String, password: String){

// Handle Authentication challenge

let delegate: Alamofire.SessionDelegate = LoginService.Manager.delegate
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!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = LoginService.Manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}

//Web service Request
let parameters = [
"username": "TEST",
"password": "PASSWORD",
]
let header: HTTPHeaders = ["Accept": "application/json"]
LoginService.Manager.request("https://devportal:8443/rest/login", method: .post, parameters: parameters, encoding: JSONEncoding(options: []),headers :header).responseJSON { response in
debugPrint(response)

if let json = response.result.value {
print("JSON: \(json)")
}
}



}
}

你还应该如下配置你的plist

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>devportal</key>
<dict>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
</plist>

Do not enter IP or port numbers in your NSExceptiondomains. It won'twork. If you are trying to connect to a web server with IP address,map the IP address to a domain by adding a host entry in etc/hostsfile in your mac and then use the domain name in NSExceptionDomains

IMPORTANT: Do not use this code in production as this puts your usersinformation at risk, by bypassing auth challenge.

关于ios - Alamofire 4.0 的证书无效问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40765314/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com