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?

+4


source to share


2 answers


URLSessionConfiguration

      

additional headers are needed.



let configuration.httpAdditionalHeaders = ["Proxy-Authorization":  Request.authorizationHeader(user: "user", password: "password") ]

      

+1


source


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 title Proxy-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 want kCFStreamPropertyHTTPProxyHost

    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.

+1


source







All Articles