Как подключиться к самоподписанным серверам с помощью Alamofire 1.3
Я получаю следующую ошибку при подключении к самоподписанному серверу.
Ошибка домена = NSURLErrorDomain Code = -1202 "Сертификат для этого сервера недействителен. Возможно, вы подключаетесь к серверу, который притворяется" maskeddomain.com ", который может поставить вашу конфиденциальную информацию под угрозу". UserInfo = 0x7fb6dec259e0 {NSURLErrorFailingURLPeerTrustErrorKey =, NSLocalizedRecoverySuggestion = Хотелось бы подключиться к серверу в любом случае?, _kCFStreamErrorCodeKey = -9813, NSUnderlyingError = 0x7fb6dbe0dd90 "Операция не может быть выполнена. (KCFErrorDomainCFNetwork error -1202.)"
Похоже, Alamofire 1.3 (https://github.com/Alamofire/Alamofire#security) позволяет отключить эту проверку. Кто-нибудь реализовал это? Я использую API Alamofire в моем быстром проекте, не знаю, где именно должен быть реализован "Server Trust Policy Manager". Пожалуйста, совет.
Ответы
Ответ 1
Существует способ изменения политики доверия сервера для общего экземпляра менеджера Alamofire, но это не рекомендуется. Вместо этого вы должны создать свой собственный настраиваемый экземпляр менеджера. Вот рекомендуемое решение, код Swift 2.0 с Alamofire от ветки swift-2.0, скомпилированный в Xcode7 beta 5.
Создание настраиваемого экземпляра менеджера
Поскольку вы не будете использовать метод запроса в Alamofire, но вместо этого используйте его в своем настраиваемом менеджере, вам нужно подумать о том, где хранить менеджера. То, что я делаю, это хранить его как статичное в моей сетевой оболочке (класс, который использует Alamofire и имеет дело с моими потребностями в сети). Я настроил его так:
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
}()
Следующий шаг - переключить все ваши вызовы, которые используют Alamofire.request()
с Manager.request()
, поэтому у вас должно быть что-то вроде этого:
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
}
})
Если вы все равно хотите изменить общий экземпляр менеджера, перейдите здесь для получения дополнительной информации.
Ответ 2
Конфигурация менеджера для Swift 3 или Swift 4 и 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
}()
Ответ 3
Пример опубликован прямо в README, демонстрируя, как отключить оценку, если вам нужно это сделать.
Поскольку вам понадобится создать собственный экземпляр Manager
, вам нужно сделать что-то вроде следующего:
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)
)
}()
}
Это позволит вам создавать запросы с объектом NetworkManager.sharedInstance.defaultManager
.
Ответ 4
Другой подход для моего проекта. ServerTrustPolicyManager
- это класс open
, а функция serverTrustPolicy
тоже open
. Поэтому он может быть отменен.
// 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.
}
}
Тогда
let trustPolicies = MyServerTrustPolicyManager(policies: [:])
let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)
UPDATE @2018,01
Для запуска ServerTrustPolicyManager
необходимо сконфигурировать проект Info.plist
. Я нашел решение, подробно на этом посту, cnoon comment @1 ноября 2015 г..
![введите описание изображения здесь]()
Например, если есть URL-адреса с именем site1.foo.com
, site2.foo.com
,....
Затем добавьте словарь App Transport Security Settings
→ Exception Domains
→ foo.com
со следующими записями.
- NSExceptionRequiresForwardSecrecy: NO
- NSExceptionAllowsInsecureHTTPLoads: ДА
- NSIncludesSubdomains: YES
Более подробно вы можете сослаться на сообщение.
Ответ 5
В любом случае, ответ @cnoon почти полный. Но я столкнулся с другой проблемой проверки ssl, поэтому я хочу разместить здесь свой код, если кто-то может получить от него помощь. Менеджер init:
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))
Затем используйте диспетчер для запроса:
// 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.: это быстрый образец 2.3
Ответ 6
Замена https на http в моем baseurl решила мою проблему