Swift 2 - Xcode 7.0 Не удается получить доступ к сайту HTTPS с ненадежным SSL-сертификатом
Эксперты, я новичок в IOS 9/XCODE 7/Swift 2 Development Kit
Я пытаюсь создать приложение ios, которое просто направляется на веб-приложение в протоколе HTTPS. Ниже мой код пока находится в 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.
}
}
Во время создания моего приложения он показывает следующее сообщение об ошибке
2015-10-01 01: 05: 13.879 Тестировщик веб-страниц [2947: 31838] Ошибка загрузки NSURLSession/NSURLConnection (kCFStreamErrorDomainSSL, -9807)
и если я попытаюсь создать свое приложение вместо https://domain:8443/path/to/page "с помощью http://www.apple.com" его работы прекрасны.
Я могу получить доступ к своему веб-приложению в Safari, и он просит принять риски безопасности. и я принимаю его, и я могу получить доступ к моему Приложению.
Помогите мне исправить мои проблемы, спасибо заранее.
Ответы
Ответ 1
Наконец, я исправил его
Xcode по умолчанию отказывает сертификаты самоподписанных сертификатов без доверенности.
мы можем переопределить это с помощью NSURLConnection
и можем связываться с самозаверяющим сервером, поскольку у нас есть возможность контролировать аутентификацию с помощью дополнительных методов делегатов, которые недоступны для UIWebView. Поэтому, используя connection:didReceiveAuthenticationChallenge
, мы можем пройти аутентификацию против самоподписанного сервера.
Ссылки
Документы NSURLAuthenticationChallenge, @Lilo Lu Question
Я разрешил свой вопрос в следующих шагах
Шаг 1: Определен метод NSURLConnection
в viewDidLoad()
моего viewController.swift следующим образом
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)
}
Шаг 2: используемые методы делегатов 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)
}
}
и это сработало!!
Ответ 2
Вы можете добавить следующее к своему plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
![введите описание изображения здесь]()
Ответ 3
В Swift 3.
Шаг 1. Добавьте NSURLConnectionDelegate
в свой диспетчер просмотра, чтобы перезаписать методы.
class ViewController: UIViewController, NSURLConnectionDelegate {
Шаг 2. Переопределить 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)
}
Шаг 3 Перезаписать canAuthenticateAgainstProtectionSpace
и 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)
}
}
Спасибо Navas Basheer за оригинальное решение! Сэкономил мне немного времени
Ответ 4
1- Создать категорию "NSURLRequestCategory" → после импорта этой категории в файл моста, созданный с помощью xcode (не забудьте, чтобы xCode создавал один, если вы этого не сделали) и поместите этот код:
@implementation NSURLRequest (NSURLRequestCategory)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
@end
Создайте свой запрос на загрузку UIWebView обычно:
webView.delegate = self
let myURL = URL(string: Constants.URL_DOMAINE)
let request = URLRequest(url: myURL!)
webView.loadRequest(request)
Наслаждайтесь: D
Ответ 5
изменить Info.plist, Добавить:
- Настройки безопасности при работе с портами
- Разрешить произвольные нагрузки, значение YES
он работает для меня, XCode 7.3