gpt4 book ai didi

ios - 在 ServerTrust 之后不调用 'didReceiveChallenge' 进行 HttpBasic 身份验证

转载 作者:技术小花猫 更新时间:2023-10-29 11:05:48 26 4
gpt4 key购买 nike

我正在将 iOS 应用程序从 NSURLConnection 转换为 NSURLSession。

服务器使用 https(由公认的 CA 签名的证书)和基本身份验证进行交互。

我没有使用完成 block 来返回数据,而是使用自定义委托(delegate)。我在别处看到,使用自定义委托(delegate)意味着我应该响应 AuthenticationChallenges 而不是依赖 CredentialStorage(这也行不通,但那是另一个问题)。

我的问题是,对 ServerTrust 进行了一次质询,但对 HttpBasic 身份验证不会再次调用。所以,我的 session 超时了。

我已经尝试为“defaultSession dataTaskWithRequest”使用完成 block 而不是自定义委托(delegate),只是想看看我是否可以通过这一点,但这没有什么区别。我还尝试将 CredentialStorage 用于 HttpBasic 凭据,但如上所述,我并不高兴。

这让我难住了。有什么想法吗?

(void)URLSession:(NSURLSession *)connection
// task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
#if 1 && defined(DEBUG)
NSLog (@"didReceiveChallenge: Using SSL");
#endif // DEBUG

if ([challenge.protectionSpace.host isEqualToString:HOST])
{
#if 1 && defined(DEBUG)
NSLog (@"didReceiveChallenge: Using Protection Space Host - %@", HOST);
#endif // DEBUG

[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
else
{
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
else

if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic] ||
[challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest])
{
#if 1 && defined(DEBUG)
NSLog (@"didReceiveChallenge: (Basic / Digest) #%ld - user: %@, password: %@",
(long)[challenge previousFailureCount], USERNAME, PASSWORD);

#endif // DEBUG

if ([challenge previousFailureCount] == 0)
{
#if 1 && defined(DEBUG)
NSLog (@"didReceiveChallenge: previousFailureCount == 0");
#endif // DEBUG

NSURLCredential *newCredential;

newCredential = [NSURLCredential credentialWithUser:USERNAME
password:PASSWORD
persistence:NSURLCredentialPersistenceForSession];

[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];

}
else
{
[[challenge sender] cancelAuthenticationChallenge:challenge];

// inform the user that the user name and password
// in the preferences are incorrect

#if 1 && defined(DEBUG)
NSLog (@"didReceiveChallenge: Failed Authentication");
#endif // DEBUG

// ...error will be handled by connection didFailWithError
}
}
#ifdef DEBUG
else
{
NSLog(@"didReceiveChallenge: Not handled!");
}

#endif // DEBUG
}

最佳答案

排名不分先后:

  • 您实际上已经为相关的特定主机完全禁用了 TLS,因为您没有以任何有意义的方式检查证书,而只是检查它是否提供了与给定主机名匹配的证书。这是非常非常危险的。相反,您需要对证书执行一些自定义验证(例如,检查 key 是否与固定 key 匹配或检查它是否由已知可信的内部证书签名),然后仅在验证时执行您正在执行的操作.
  • 通过指定您不想让服务器提供其证书,您(我认为)有效地完全破坏了所有其他主机的 TLS。在这种情况下,您应该要求进行默认处理。
  • 对于任何其他挑战类型,您的方法是忽略挑战,这意味着连接将永远挂起,永远不会取得进展。在这些情况下,您也应该要求进行默认处理。否则,当(而不是如果)您被要求提供客户端证书时,您的连接将似乎挂起并最终会超时。
  • 您对实际通知的处理有误。您应该永远不要使用 NSURLSession 调用质询发送者的方法。您必须调用完成方法。否则, session 将继续等待您调用它,直到请求超时。

我不确定代码中是否还有其他错误,但所有这三个错误都可能导致严重的不当行为,其中一个是主要的安全漏洞。首先解决这些问题,如果仍然不起作用,请添加更多评论。 :-)

关于ios - 在 ServerTrust 之后不调用 'didReceiveChallenge' 进行 HttpBasic 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41417558/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com