gpt4 book ai didi

iOS NSURLAuthenticationMethodClientCertificate 未请求与 ActiveSync 服务器

转载 作者:可可西里 更新时间:2023-11-01 03:38:42 27 4
gpt4 key购买 nike

我正在尝试在我正在开发的 ActiveSync 客户端中实现证书身份验证。使用证书身份验证的代码可能有效,但截至目前,服务器,或者更准确地说,iOS 库对服务器响应的解释,对我来说似乎是不正确的。这是我的代码:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
NSString *authenticationMethod = [protectionSpace authenticationMethod];

if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])
{
NSURLCredential* credential = [ self buildCredentialClientCert];

if ( credential == nil )
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
else if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
.... // do other stuff

问题是,即使我知道服务器支持客户端证书身份验证,当我设置断点时 authenticationMethod 始终设置为 NSURLAuthenticationMethodServerTrust

原始 HTTPS 服务器响应包含以下内容:

Error Code: 403 Forbidden. The page requires a client certificate as part of the authentication process. If you are using a smart card, you will need to insert your smart card to select an appropriate certificate. Otherwise, contact your server administrator. (12213)

我的问题是,什么决定身份验证质询是 NSURLAuthenticationMethodServerTrust 还是 NSURLAuthenticationMethodClientCertificate

最佳答案

由于没有人回答这个问题,而我最终确实找到了一个可行的解决方案,所以就在这里。

服务器信任不是服务器对客户端的挑战,它是客户端验证服务器提供的信任的机会。考虑到这一点,下面的代码不会验证这种信任,但它可以。

通常您会获得 NSURLAuthenticationMethodServerTrust,随后您会获得 NSURLAuthenticationMethodClientCertificate。这不是非此即彼。这是工作代码。

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
NSString *authenticationMethod = [protectionSpace authenticationMethod];

if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate] && self.accountCertKeychainRef != nil)
{
SecIdentityRef identity = [KeychainUtilities retrieveIdentityWithPersistentRef:self.accountCertKeychainRef];

NSURLCredential* credential = [CertificateUtilities getCredentialFromCert:identity];

if ( credential == nil )
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
else if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}
else if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM] || [authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic])
{
self.lastProtSpace = [challenge protectionSpace];
if ([challenge previousFailureCount] > 2)
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] useCredential:[self buildCredential] forAuthenticationChallenge:challenge];
}

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

对于下面的问题,您可以通过以下方式获取标识:

+ (SecIdentityRef)copyIdentityAndTrustWithCertData:(CFDataRef)inPKCS12Data password:(CFStringRef)keyPassword
{
SecIdentityRef extractedIdentity = nil;
OSStatus securityError = errSecSuccess;

const void *keys[] = {kSecImportExportPassphrase};
const void *values[] = {keyPassword};
CFDictionaryRef optionsDictionary = NULL;

optionsDictionary = CFDictionaryCreate(NULL, keys, values, (keyPassword ? 1 : 0), NULL, NULL);

CFArrayRef items = NULL;
securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);

if (securityError == errSecSuccess) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);

// get identity from dictionary
extractedIdentity = (SecIdentityRef)CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
CFRetain(extractedIdentity);
}

if (optionsDictionary) {
CFRelease(optionsDictionary);
}

if (items) {
CFRelease(items);
}

return extractedIdentity;
}

对于那些感兴趣的人,这里是 getCredentialForCert:

+ (NSURLCredential *)getCredentialFromCert:(SecIdentityRef)identity
{
SecCertificateRef certificateRef = NULL;
SecIdentityCopyCertificate(identity, &certificateRef);

NSArray *certificateArray = [[NSArray alloc] initWithObjects:(__bridge_transfer id)(certificateRef), nil];
NSURLCredentialPersistence persistence = NSURLCredentialPersistenceForSession;

NSURLCredential *credential = [[NSURLCredential alloc] initWithIdentity:identity
certificates:certificateArray
persistence:persistence];

return credential;
}

关于iOS NSURLAuthenticationMethodClientCertificate 未请求与 ActiveSync 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21537203/

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