How do I authenticate the proxy in the url?
Hey. I am trying to add a proxy with credentials to my application, but whenever I tried I got the following warning (In Xcode):
*** WARNING: CFMachPortSetInvalidationCallBack() called on a CFMachPort with a Mach port (0x900b) which does not have any send rights. This is not going to work. Callback function: 0x181bcf524
Also got a warning with the following description
Authentication for HTTP proxy
MyProxyHost
MyProxyPort
When I cancel the popup it calls the following method
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
I am debugging a task in Xcode console and got the following debugDescription:
po challenge.protectionSpace.debugDescription
"<NSURLProtectionSpace: 0x12f685ad0>: Host: MyProxyHost, Server:http, Auth-Scheme:NSURLAuthenticationMethodHTTPBasic, Realm:(null), Port: MyProxyPort, Proxy:YES, Proxy-Type:http"
My question is how to work with proxy authentication?
My code:
func getURLCredential() -> URLCredential {
let credential = URLCredential(user: user, password: password, persistence: URLCredential.Persistence.forSession)
return credential
}
From the dictionary below, I can hit the proxy, but I cannot authenticate the proxy.
// Create an NSURLSessionConfiguration that uses the proxy
let proxyDict: [AnyHashable: Any]? = [(kCFNetworkProxiesHTTPEnable as AnyHashable): Int(1), (kCFNetworkProxiesHTTPProxy as AnyHashable): proxyServerString, (kCFNetworkProxiesHTTPPort as AnyHashable): proxyPortNumber, (kCFProxyUsernameKey as AnyHashable): userNameKey, (kCFProxyPasswordKey as AnyHashable): password]
let configuration = URLSessionConfiguration.default
configuration.connectionProxyDictionary = proxyDict
I tried several methods below:
let loginString = String(format: "%@:%@", user, password)
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()// base64EncodedData(options: [])
configuration.httpAdditionalHeaders = ["Authorization" : base64LoginString]
Another way:
let protectionSpace:URLProtectionSpace = URLProtectionSpace(host: proxyHost, port: proxyPort, protocol: "http", realm: nil, authenticationMethod: NSURLAuthenticationMethodHTTPBasic)
let credentialStorage = URLCredentialStorage.shared//.allCredentials
credentialStorage.set(getURLCredential(), for: protectionSpace)
configuration.urlCredentialStorage = credentialStorage
ANOTHER WAY:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("Challenge:")
guard challenge.previousFailureCount == 0 else {
print("Previous Failure Count = \(challenge.previousFailureCount)")
print("Cancelling Challenge\n")
challenge.sender?.cancel(challenge)
// Inform the user that the user name and password are incorrect
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
print("Use Credential ....\n")
completionHandler(.useCredential, self.getURLCredential())
}
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if challenge.previousFailureCount > 0
{
print("Alert Please check the credential")
debugPrint("Alert Please check the credential")
completionHandler(.cancelAuthenticationChallenge, nil)
}
challenge.sender?.use(self.getURLCredential(), for: challenge)
completionHandler(.useCredential, self.getURLCredential())
}
it is impossible to verify the authenticity.
Please suggest me how to authenticate the proxy server in swift 3?
source to share
Each of your approaches has different mistakes:
The header
Authorization
is for authenticating yourself to a remote server, not a proxy. You want to set a titleProxy-Authorization
.The kCFProxy * keys you are using are not valid in a proxy dictionary (and therefore using a dictionary as a data structure is a fundamentally bad project, BTW, for people developing future APIs). These keys are used exclusively for setup
CF(Read|Write)Stream
. You wantkCFStreamPropertyHTTPProxyHost
friends too. See this closely related question for a valid example of a proxy dictionary .You have implemented a session-level delegate method to handle authentication issues. Unfortunately this method is not called for proxy authentication. Only the task level delegate method (
URLSession:task:...
) is called to authenticate the proxy.
source to share