URLSession and custom `WWW-Authenticate`

Hello call!

I am attempting to use the URLSession API to call an endpoint with a custom WWW-Authenticate scheme. For some reason, instead of allowing me to respond to this in the challenge handler function of my delegate, it just immediately returns with a NSURLErrorUserCancelledAuthentication error, which stops me from getting any URLResponse. I'm assuming something is going wrong internally.

Interestingly, if I use the legacy NSURLConnection API and forgo credentials altogether, I can actually get a usable URLResponse (albeit in the 400 range).

class MyConnectionDelegate: NSObject, NSURLConnectionDataDelegate {
  func connection(_ connection: NSURLConnection, didReceive response: URLResponse) {
    print("didReceive response")
    print(response)
  }
  func connectionShouldUseCredentialStorage(_ connection: NSURLConnection) -> Bool {
    return false
  }
}

let request = NSURLRequest(
  url: URL(string: "[XXX]")!)

let connection = NSURLConnection(
  request: request as URLRequest,
  delegate: MyConnectionDelegate()
)
connection?.start()
RunLoop.main.run()

This is obviously not preferable. Is there a way to do this with the URLSession API? Or at least see what's going wrong internally?

OK. I figured it out. I just have to set the Authorization header manually.

FYI, urlSession(_:didReceive:completionHandler:) is only called when the server actually provides a authorization challenge of some kind, such as the WWW-Authenticate: Basic expected when using HTTP Basic, but only if the server actually replies with such a challenge. Generally URLSession doesn't consider response codes when calling various delegates, so the authentication challenge only happens for a response containing one of the supported challenge types, like basic or digest. (The same delegate is also reused for things like TLS verification, which can be rather confusing.)

1 Like