4

嗨,我正在尝试向我的应用程序添加带有凭据的代理,但每当我尝试时,我都会收到以下(在 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

还收到以下说明的警报

Authentication for HTTP proxy
MyProxyHost
MyProxyPort

当我取消弹出窗口时,它正在调用以下方法

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)

我在Xcode 控制台中调试挑战并得到以下 debugDescription:

po challenge.protectionSpace.debugDescription
"<NSURLProtectionSpace: 0x12f685ad0>: Host: MyProxyHost, Server:http, Auth-Scheme:NSURLAuthenticationMethodHTTPBasic, Realm:(null), Port: MyProxyPort, Proxy:YES, Proxy-Type:http"

我的问题是如何处理代理身份验证?

我的代码:

func getURLCredential() -> URLCredential {

        let credential = URLCredential(user: user, password: password, persistence: URLCredential.Persistence.forSession)
        return credential
    }

从下面的字典中,我可以访问代理但无法验证代理。

// 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

我尝试了以下几种方法但失败了:

let loginString = String(format: "%@:%@", user, password)
        let loginData = loginString.data(using: String.Encoding.utf8)!
        let base64LoginString = loginData.base64EncodedString()// base64EncodedData(options: [])
configuration.httpAdditionalHeaders = ["Authorization" : base64LoginString]

其他方式:

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

其他方式:

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())
    }

无法进行身份验证。

请建议我如何在 swift 3 中验证代理?

4

2 回答 2

1

您的每种方法都有不同的错误:

  • Authorization头用于向远程服务器验证您自己,而不是代理。你会想要设置Proxy-Authorization标题。

  • 您使用的 kCFProxy* 键在代理字典中无效(这就是为什么使用字典作为数据结构从根本上来说是一种糟糕的设计,顺便说一句,对于设计未来 API 的人来说)。这些键仅在配置CF(Read|Write)Stream. 你想kCFStreamPropertyHTTPProxyHost和朋友。有关有效的代理字典示例,请参阅这个密切相关的问题

  • 您实现了用于处理身份验证挑战的会话级委托方法。不幸的是,代理身份验证不会调用该方法。只有任务级委托方法 ( URLSession:task:...) 被调用以进行代理身份验证。

于 2018-06-27T06:04:57.590 回答
1
URLSessionConfiguration

需要额外的标题。

let configuration.httpAdditionalHeaders = ["Proxy-Authorization":  Request.authorizationHeader(user: "user", password: "password") ]
于 2019-08-19T15:39:32.457 回答