Reputation: 107
I need to handle the challenge when I try to get the json from my internal web server. I followed this from a previous question. Here is my code
let defaultManager: Alamofire.SessionManager = {
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"myhttpsinternaldomain.org": .disableEvaluation
]
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
return Alamofire.SessionManager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}()
let url = URL(string: urlString)
let username = "user"
let password = "password"
let header = ["user": username, "password": password]
defaultManager.request(url!, method: .get, headers: header).responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
This is the error I receive
Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://myhttpsinternaldomain.org, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://myhttpsinternaldomain.org}
I found this but I don't have the tokens in my project. I want to just user the username and password or ignore the challenge
Please any help
Upvotes: 0
Views: 4652
Reputation: 107
Got it! Or rather I found the right page to that led me to the answer. Github Page Server Trust Policy Manager and connect to self signed servers using Alamofire
Originally I would get a 310 error, after the SSL would deny my authentication.
Then I added the manager class I posted originally and received a -999 error saying that it was "cancelled". Thanks to the Github Page above the reason is because I needed to
"Make sure to keep a reference to the new SessionManager instance, otherwise your requests will all get cancelled when your sessionManager is deallocated."
So I created a NetworkManager class thanks to the second stackoverflow page, and called it in my alamofire request.
Here is the code below that works, hopefully this will save someone a lot of time.
// Network Manager outside view controller
class NetworkManager {
static let sharedInstance = NetworkManager()
let manager: Alamofire.SessionManager = {
let serverTrustPolicies: [String: ServerTrustPolicy] = [
"https://mydomainthatwasdrivingmebananas.com": .pinCertificates(
certificates: ServerTrustPolicy.certificates(),
validateCertificateChain: true,
validateHost: true),
"mydomainthatwasdrivingmebananas.com": .disableEvaluation
]
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
return Alamofire.SessionManager(
configuration: configuration,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
}()
}
Then the Alamofire call
// Inside ViewController ViewDidLoad
NetworkManager.sharedInstance.manager.request("https://mydomainthatwasdrivingmebananas.com", method: .get).responseJSON{ response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
P.S the JSON() method is swifty JSON in case anyone was confused
Upvotes: 6
Reputation: 1614
You cannot send username and password like this in the header like you do in postman. You have to change them to base64. This is what postman does in the background when he adds your credentials to the header.
// Your hostname and endpoint
let hostname = "myhttpsinternaldomain.org"
let cert = "YOUR_CERT" // e.g. for cert.der, this should just be "cert"
// Set up certificates
let pathToCert = Bundle.main.path(forResource: cert, ofType: "der")
let localCertificate = NSData(contentsOfFile: pathToCert!)
let certificates = [SecCertificateCreateWithData(nil,
localCertificate!)!]
// Configure the trust policy manager
let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
certificates: certificates,
validateCertificateChain: true,
validateHost: true
)
let serverTrustPolicies = [hostname: serverTrustPolicy]
let serverTrustPolicyManager = ServerTrustPolicyManager(policies:
serverTrustPolicies)
// Configure session manager with trust policy
let defaultManager = Alamofire.SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: serverTrustPolicyManager
)
let url = URL(string: urlString)
let user = "user"
let password = "password"
let base64 = "\(user):\(password)".toBase64()
let header = [
"Authorization": "Basic \(base64)"
]
//Added encoding type in the request. Change and try other types too. Like JSONEncoding.default
defaultManager.request(url!, method: .get, encoding: URLEncoding.default ,headers: header).responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
extension String {
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}
Upvotes: 0