This code has worked fine for the past couple of years, but after dusting off an old project it no longer works in Xcode 15. I have the 'URLSessionDelegate' correctly set and below is a simplified method:
'''
let user = "user"
let pass = "pass"
let token = "123456"
let url = "https://192.168.17.254:7443/api/auth/login"
let authUrl = URL(string: url)
var authRequest = URLRequest(url: authUrl)
authRequest.httpMethod = "POST"
let authBody = ["username": user, "password": pass, "token": token]
authRequest.httpBody = try! JSONSerialization.data(withJSONObject: authBody, options: .prettyPrinted)
authRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
authRequest.setValue("TOKEN=", forHTTPHeaderField: "Cookie")
let authSessionConfig = URLSessionConfiguration.default
let authSession = URLSession(configuration: authSessionConfig, delegate: self, delegateQueue: nil)
authSession.dataTask(with: authRequest) { (data, response, error) in
//Never reaches code here, no error no data
}.resume
'''
I also have the delegate for 'didReceive challenge' which I have tried a few versions of from other questions on here ..
'''
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("didRecieve URLAuthenticationChallenge")
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
print("send credential Server Trust")
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: "username", password: "password", persistence:URLCredential.Persistence.forSession)
challenge.sender!.use(defaultCredentials, for: challenge)
}else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM{
print("send credential NTLM")
} else{
challenge.sender!.performDefaultHandling!(for: challenge)
}
}
'''
As I say this has worked fine previously but now I get API MISUSE errors, and it infers the completion handler wasn't called even though it was, as you can see the print statement in the output.
I am connecting to a local web server that uses HTTPS on port 7443 but doesn't have any certificates etc, I thought about posting a sample project but without the local web server you wouldn't be able to reproduce it. I suspect it some new ATS security in Xcode 15 but I have no idea what it wants me to do to fix it.
This code is incorrect:
challenge.sender!.use(credential, for: challenge)
It's not up to you to call use()
here. It's up to you to call the completion handler (which is what the error is saying).
The code you want here is:
completionHandler(.useCredential, credential)
Similarly for the other legs of your function.
For complete details see Handling an authentication challenge.