URLSession에서 SSL 오류가 발생했을 때 Safari와 마찬가지로 액세스 할 수있게합니다.
12913 단어 iOSSwiftURLSessionmacosSSL
요약
SecTrust
를 사용하여 SSL 오류를 해결합니다.
개요
Safari에서 브라우징하는 경우 사이트에 '연결이 비공개 없음'으로 표시될 수 있습니다.
이에 대해 "자세히 보기"→"이 웹사이트를 열람"으로 함으로써 사용자의 책임으로 사이트를 열람할 수 있습니다.
이것을 URLssion에서도하고 싶습니다.
Info.plist 설정
Info.plist를 App Transport Security Settings
로 설정해야 합니다.Exception Domains
→ 원하는 도메인 → NSExceptionAllowsInsecureHTTPLoads
를 YES로 설정합니다.
이 예에서는 필드 d SL. 작은 m의 하위 도메인에서도 테스트하고 싶으므로 NSIncludesSubdomains
도 YES로 둡니다.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>badssl.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
URLSession에 구현
첫째, URLession은 delegate를 붙일 수 있도록 초기화합니다.
그리고, URLSessionTaskDelegate
등, 목적의 델리게이트를 설정해, urlSession(_:didReceive:completionHandler:)
등으로 핸들링해 줍니다.
코드
class ViewController: UIViewController {
lazy var session: URLSession = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
override func viewDidLoad() {
super.viewDidLoad()
let task = session.dataTask(with: URL(string: "https://revoked.badssl.com")!)
task.resume()
}
}
extension ViewController: URLSessionTaskDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print(#function,#line,"\(String(describing: error))")
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
//サーバー信頼チェック以外はデフォルトの挙動を行う
guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
let serverTrust = challenge.protectionSpace.serverTrust else {
completionHandler(.performDefaultHandling, nil)
return
}
// Trustを確認する
SecTrustEvaluateAsyncWithError(serverTrust, DispatchQueue.global()) { (secTrust, trusted, error) in
if trusted {
completionHandler(.performDefaultHandling, nil) // 信頼できる場合デフォルトの挙動を行う
} else {
// エラーメッセージを表示
let title:String
if let error = error {
title = error.localizedDescription
} else {
title = "接続はプライベートではありません"
}
DispatchQueue.main.async {
//アラートを表示して、ユーザーに選択を促す
let alert = UIAlertController(title: title,
message: "それでもサーバに接続しますか?",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "接続する", style: .destructive, handler: { (alertAction) in
completionHandler(.useCredential, URLCredential(trust: secTrust))
}))
alert.addAction(UIAlertAction(title: "接続しない", style: .cancel, handler: { (alertAction) in
completionHandler(.cancelAuthenticationChallenge, nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
}
}
}
코드 설명
urlSession(_:didReceive:completionHandler:)
는 기본 인증 시 등도 호출됩니다만, 이번은 서버의 신뢰에 대한 처리만이므로 NSURLAuthenticationMethodServerTrust
그 이외의 경우는 특히 대처의 필요는 이번은 고려하지 않기 때문에 리턴을 합니다만, completionHandler를 반드시 호출할 필요가 있으므로, .performDefaultHandling
를 호출해 둡니다.
우선, SecTrustEvaluateAsyncWithError
에 secTrust 를 건네주어 신뢰할 수 있을지 어떨지를 콜백 받습니다.
콜백에서는 신뢰 결과가 반환되어 신뢰할 수 있다고 판단할 수 있는 경우는 그대로 .performDefaultHandling
로 처리 계속할 수 있습니다만, 신뢰할 수 없게 되었을 경우, 경고를 표시해 유저에게 판단을 받게 합니다.
CFError 의 localizedDescription 에는 에러의 원인이 포함되어 있으므로, 그것을 유저에게 제시해, 유저가 접속 가능이라고 판단했을 경우는 .useCredential
그리고 처리 계속할 수 있습니다.
사용자가 연결하지 않는다고 판단되면 .cancelAuthenticationChallenge
에서 연결을 취소합니다.
액세스시 이미지
자체 인증서
만료됨
revoked
요약
잡자! SecTrust!
Reference
이 문제에 관하여(URLSession에서 SSL 오류가 발생했을 때 Safari와 마찬가지로 액세스 할 수있게합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/coe/items/233691f7cae297025e87
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Safari에서 브라우징하는 경우 사이트에 '연결이 비공개 없음'으로 표시될 수 있습니다.
이에 대해 "자세히 보기"→"이 웹사이트를 열람"으로 함으로써 사용자의 책임으로 사이트를 열람할 수 있습니다.
이것을 URLssion에서도하고 싶습니다.
Info.plist 설정
Info.plist를
App Transport Security Settings
로 설정해야 합니다.Exception Domains
→ 원하는 도메인 → NSExceptionAllowsInsecureHTTPLoads
를 YES로 설정합니다.이 예에서는 필드 d SL. 작은 m의 하위 도메인에서도 테스트하고 싶으므로
NSIncludesSubdomains
도 YES로 둡니다. <key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>badssl.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
URLSession에 구현
첫째, URLession은 delegate를 붙일 수 있도록 초기화합니다.
그리고,
URLSessionTaskDelegate
등, 목적의 델리게이트를 설정해, urlSession(_:didReceive:completionHandler:)
등으로 핸들링해 줍니다.코드
class ViewController: UIViewController {
lazy var session: URLSession = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
override func viewDidLoad() {
super.viewDidLoad()
let task = session.dataTask(with: URL(string: "https://revoked.badssl.com")!)
task.resume()
}
}
extension ViewController: URLSessionTaskDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print(#function,#line,"\(String(describing: error))")
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
//サーバー信頼チェック以外はデフォルトの挙動を行う
guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
let serverTrust = challenge.protectionSpace.serverTrust else {
completionHandler(.performDefaultHandling, nil)
return
}
// Trustを確認する
SecTrustEvaluateAsyncWithError(serverTrust, DispatchQueue.global()) { (secTrust, trusted, error) in
if trusted {
completionHandler(.performDefaultHandling, nil) // 信頼できる場合デフォルトの挙動を行う
} else {
// エラーメッセージを表示
let title:String
if let error = error {
title = error.localizedDescription
} else {
title = "接続はプライベートではありません"
}
DispatchQueue.main.async {
//アラートを表示して、ユーザーに選択を促す
let alert = UIAlertController(title: title,
message: "それでもサーバに接続しますか?",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "接続する", style: .destructive, handler: { (alertAction) in
completionHandler(.useCredential, URLCredential(trust: secTrust))
}))
alert.addAction(UIAlertAction(title: "接続しない", style: .cancel, handler: { (alertAction) in
completionHandler(.cancelAuthenticationChallenge, nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
}
}
}
코드 설명
urlSession(_:didReceive:completionHandler:)
는 기본 인증 시 등도 호출됩니다만, 이번은 서버의 신뢰에 대한 처리만이므로 NSURLAuthenticationMethodServerTrust
그 이외의 경우는 특히 대처의 필요는 이번은 고려하지 않기 때문에 리턴을 합니다만, completionHandler를 반드시 호출할 필요가 있으므로, .performDefaultHandling
를 호출해 둡니다.우선,
SecTrustEvaluateAsyncWithError
에 secTrust 를 건네주어 신뢰할 수 있을지 어떨지를 콜백 받습니다.콜백에서는 신뢰 결과가 반환되어 신뢰할 수 있다고 판단할 수 있는 경우는 그대로
.performDefaultHandling
로 처리 계속할 수 있습니다만, 신뢰할 수 없게 되었을 경우, 경고를 표시해 유저에게 판단을 받게 합니다.CFError 의 localizedDescription 에는 에러의 원인이 포함되어 있으므로, 그것을 유저에게 제시해, 유저가 접속 가능이라고 판단했을 경우는
.useCredential
그리고 처리 계속할 수 있습니다.사용자가 연결하지 않는다고 판단되면
.cancelAuthenticationChallenge
에서 연결을 취소합니다.액세스시 이미지
자체 인증서
만료됨
revoked
요약
잡자! SecTrust!
Reference
이 문제에 관하여(URLSession에서 SSL 오류가 발생했을 때 Safari와 마찬가지로 액세스 할 수있게합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/coe/items/233691f7cae297025e87
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
잡자! SecTrust!
Reference
이 문제에 관하여(URLSession에서 SSL 오류가 발생했을 때 Safari와 마찬가지로 액세스 할 수있게합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/coe/items/233691f7cae297025e87텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)