ios - 当代理质询提供带有 Proxy-Authenticate header 的 407 响应时,弹出代理身份验证对话框

标签 ios objective-c proxy proxy-authentication

在我的应用程序中,我为 NSURLSessionConfiguration 对象配置了一个代理,因此应用程序可以使用该代理。当代理需要身份验证时,App 会通过委托(delegate)方法“URLSession:task:didReceiveChallenge:completionHandler:”询问用户名和密码,并确保请求可以继续。

在 HTTP 请求中正常,但 HTTPS 请求会弹出一个对话框,说明需要代理身份验证,并让用户选择“稍后”执行此操作或直接转到系统设置。

此外,即使在上面 NSUrlSession 的委托(delegate)方法“didReceiveChallenge”之前弹出对话框,应用程序也没有机会在 iOS 显示之前提供凭据。

有没有其他人看到这个并且知道如何解决这个问题?

代理服务器响应头 :

需要 HTTP/1.1 407 代理身份验证

内容类型:文本/html

X-Squid-错误:ERR_CACHE_ACCESS_DENIED 0

代理验证:基本领域="基本"

代理验证:摘要领域=“摘要”,
nonce="xxxxxxxxxxxxxxxxxxxxxxxxxxx", qop="auth", stale=false

X-Cache:来自 proxy.xxxx.com 的 MISS

通过:1.1 proxy.xxxx.com

我的演示代码 :

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
config.connectionProxyDictionary = @{
                                     @"HTTPEnable" : @(1),
                                     (NSString *)kCFStreamPropertyHTTPProxyHost  : @"proxy.xxxx.com",
                                     (NSString *)kCFStreamPropertyHTTPProxyPort  : @(1234),
                                     @"HTTPSEnable": @(1),
                                     (NSString *)kCFStreamPropertyHTTPSProxyHost :@"proxy.xxxx.com",
                                     (NSString *)kCFStreamPropertyHTTPSProxyPort : @(4321)
                                    };

self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.xxxxx.com"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
NSURLSessionTask  *task =  [self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSLog(@"result:%@  error: %@",data, error.description);
}];
[task resume];

#pragma 标记 - NSURLSessionTaskDelegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidReceiveChallenge:(NSURLAuthenticationChallenge *)challengecompletionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
NSLog(@"task:%@",challenge.protectionSpace.authenticationMethod);
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPDigest) {
    NSURLCredential *cren = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
    if (completionHandler) {
        completionHandler(NSURLSessionAuthChallengeUseCredential,cren);
    }
}

}

最佳答案

我找到了解决方案here .似乎这样的问题是错误。而不是使用 URLSession:task:didReceiveChallenge:completionHandler: 委托(delegate),一个好的解决方法是在 NSURLSessionConfiguration 中添加一个“Proxy-Authorization” header 。这里是基于 here 的代码:

// 1 - define credentials as a string with format:
//    "username:password"
//
NSString *username = @"USERID";
NSString *password = @"SECRET";
NSString *authString = [NSString stringWithFormat:@"%@:%@",
                        username,
                        password];

// 2 - convert authString to an NSData instance
NSData *authData = [authString dataUsingEncoding:NSUTF8StringEncoding];

// 3 - build the header string with base64 encoded data
NSString *authHeader = [NSString stringWithFormat: @"Basic %@",
                        [authData base64EncodedStringWithOptions:0]];

// 4 - create an NSURLSessionConfiguration instance
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];

// 5 - add custom headers, including the Authorization header
[configuration setHTTPAdditionalHeaders:@{
                                          @"Proxy-Authorization": authHeader
                                          }
 ];

// 6 - set proxy dictionary
NSDictionary *proxyDict = @{
                            @"HTTPEnable"  : @1,
                            (NSString *)kCFStreamPropertyHTTPProxyHost  : @"ip",
                            (NSString *)kCFStreamPropertyHTTPProxyPort  : proxyPortNumber,

                            @"HTTPSEnable" : @1,
                            (NSString *)kCFStreamPropertyHTTPSProxyHost : @"ip",
                            (NSString *)kCFStreamPropertyHTTPSProxyPort : proxyPortNumber,

                            };
configuration.connectionProxyDictionary = proxyDict;

// 7 - create an NSURLSession instance
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:nil delegateQueue:operationQueue];

关于ios - 当代理质询提供带有 Proxy-Authenticate header 的 407 响应时,弹出代理身份验证对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41036524/

相关文章:

go - Docker 提示 ALL_PROXY 环境变量为 "proxy: unknown scheme: http"

javascript - 请求的 URL "[no URL]"无效。 Node http-proxy

html - Outlook 网络客户端 html 电子邮件图像和 ImageProxy.mvc

ios - UIImagePickerController 无法正确显示 GIF

ios - 在 UIViewController 中显示 uitableview 的问题 - 未对齐

iphone - 什么时候应该使用延迟加载来加载图像?

iphone - 将 OAuth2 添加到 iOS 项目

iphone - iOS 奇怪的委托(delegate)行为?

iphone - 得到当前的纬度和经度

ios - 如何快速循环遍历 TableView 中的多个部分