我尝试使用Alamofire连接到本地网络上的Web服务器。如果我用浏览器打开网址,它会发出ssl警告。如果我只是忽略并将异常添加到浏览器中,它肯定有效
我在这个主题上阅读了不同的帖子,包括Alamofire Github页面,但是我无法让它工作。我做错了什么?
提前谢谢!
这是测试代码:
我在类ViewController下面的代码开头声明了管理器。
let manager = SessionManager(configuration: URLSessionConfiguration.default, serverTrustPolicyManager: ServerTrustPolicyManager(policies:["10.0.1.19:4491":.disableEvaluation]))
let parameters:Parameters = ["macro":"696B38D0-AF57-4991-83DD-DFD03F1A693B", "value":""]
manager.request("https://10.0.1.19:4491/authenticatedaction.html", parameters:parameters).authenticate(user:user, password:password).response {
response in
debugPrint(response)
}
这是错误:
Alamofire.DefaultDataResponse(request: Optional(https://10.0.1.19:4491/authenticatedaction.html?macro=696B38D0-AF57-4991-83DD-DFD03F1A693B&value=), response: nil, data: Optional(0 bytes), error: Optional(Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “10.0.1.19†which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x170134a00>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, NSErrorPeerCertificateChainKey=(
"<cert(0x108066e00) s: Keyboard Maestro i: Keyboard Maestro CA>"
), NSUnderlyingError=0x170259d70 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x170134a00>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9813, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x108066e00) s: Keyboard Maestro i: Keyboard Maestro CA>"
)}}, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “10.0.1.19†which could put your confidential information at risk., NSErrorFailingURLKey=https://10.0.1.19:4491/authenticatedaction.html?macro=696B38D0-AF57-4991-83DD-DFD03F1A693B&value=, NSErrorFailingURLStringKey=https://10.0.1.19:4491/authenticatedaction.html?macro=696B38D0-AF57-4991-83DD-DFD03F1A693B&value=, NSErrorClientCertificateStateKey=0}), timeline: Timeline: { "Request Start Time": 517316327.668, "Initial Response Time": 517316327.911, "Request Completed Time": 517316327.911, "Serialization Completed Time": 517316327.912, "Latency": 0.243 secs, "Request Duration": 0.243 secs, "Serialization Duration": 0.001 secs, "Total Duration": 0.244 secs }, _metrics: Optional((Task Interval) <_NSConcreteDateInterval: 0x17002b6e0> (Start Date) 2017-05-24 10:58:47 +0000 + (Duration) 0.251558 seconds = (End Date) 2017-05-24 10:58:47 +0000
(Redirect Count) 0
(Transaction Metrics) (Request) <NSURLRequest: 0x170013cd0> { URL: https://10.0.1.19:4491/authenticatedaction.html?macro=696B38D0-AF57-4991-83DD-DFD03F1A693B&value= }
(Response) (null)
(Fetch Start) 2017-05-24 10:58:47 +0000
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
(Request Start) 2017-05-24 10:58:47 +0000
(Request End) 2017-05-24 10:58:47 +0000
(Response Start) 2017-05-24 10:58:47 +0000
(Response End) (null)
(Protocol Name) (null)
(Proxy Connection) NO
(Reused Connection) YES
(Fetch Type) Unknown
))
答案 0 :(得分:8)
我终于解决了我的问题。有两个问题
1.我需要在函数外声明sessionManager
let manager = SessionManager(配置:URLSessionConfiguration.default,serverTrustPolicyManager:ServerTrustPolicyManager(策略:[&#34; localhost&#34;:。disableEvaluation]))
2.我在某处读到你需要包含主机的端口号,但实际上这对我来说是个问题
看起来你只需要编写&#34; localhost&#34;而不是&#34; localhost:443&#34;。
无论如何,这是将禁用所有地址评估的整个代码
您不需要将任何内容更改为Info.plist。 Xcode为您提供的默认Info.plist似乎可以正常工作
IOS 10.3.2,Xcode 8.3.2,来自Github的Alamofire Master分支(2017-05-23)
import UIKit
import Alamofire
class ViewController: UIViewController {
open class MyServerTrustPolicyManager: ServerTrustPolicyManager {
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
return ServerTrustPolicy.disableEvaluation
}
}
let sessionManager = SessionManager(delegate:SessionDelegate(), serverTrustPolicyManager:MyServerTrustPolicyManager(policies: [:]))
func connect() {
let user = "user"
let password = "password"
let parameters:Parameters = ["parameter1":"value1", "parameter2":"value2"]
sessionManager.request("https://localhost:443/index.php", parameters:parameters).authenticate(user:user, password:password).responseString {
response in
debugPrint(response.result.value)
} else {
debugPrint(response)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
connect()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
答案 1 :(得分:1)
在使用SessionManager
时,github上的Alamofire文档中说明了这一点:
确保保留对新SessionManager实例的引用, 否则你的请求将被取消 sessionManager已取消分配。
首先,您可以将其作为全局变量。
示例:
let sessionManager: SessionManager = {
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"10.0.1.19": .disableEvaluation
]
return SessionManager(
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}()
在开发环境中使用自签名或无效证书时,可能会在NSAppTransportSecurity
中添加NSAllowsArbitraryLoads
并将</true>
设置为Info.plist
。 请注意,不建议将其用于生产环境 。
详细说明可在Alamofire documentation:
中找到App Transport Security
随着iOS 9中的App Transport Security(ATS)的增加,它确实如此 可能是使用自定义ServerTrustPolicyManager和几个 ServerTrustPolicy对象无效。如果你不断看到 CFNetwork SSLHandshake失败(-9806)错误,你可能已经运行了 陷入这个问题。 Apple的ATS系统覆盖了整个挑战 系统,除非您在应用程序的plist中配置ATS设置 禁用足够的内容以允许您的应用评估服务器信任。
如果遇到这个问题(自签名的概率很高 证书),您可以通过添加以下内容解决此问题 到你的Info.plist。
<dict> <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>example.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> <!-- Optional: Specify minimum TLS version --> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> </dict> </dict> </dict> </dict>
是否需要将NSExceptionRequiresForwardSecrecy设置为NO 取决于您的TLS连接是否使用允许的密码 套房。在某些情况下,需要将其设置为NO。该 NSExceptionAllowsInsecureHTTPLoads必须设置为YES才能 允许SessionDelegate接收质询回调。一旦 正在调用挑战回调,即ServerTrustPolicyManager 将接管服务器信任评估。你可能还需要 如果您正在尝试,请指定NSTemporaryExceptionMinimumTLSVersion 连接到仅支持小于1.2的TLS版本的主机。
建议始终在生产中使用有效证书 的环境中。