- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我们正在尝试使用客户端 SSL 证书在企业 iOS 应用程序中进行用户身份验证。
我们如何让它发挥作用?谢谢!
最佳答案
概述:
您已经在设备钥匙串(keychain)上安装了客户端 SSL 证书。
Safari.app 和 Mail.app 可以访问这个钥匙串(keychain),而 iOS 应用程序不能。
原因是我们开发的应用程序是沙盒的,在未越狱的设备上没有任何访问权限。
由于 safari 可以访问它,因此它可以轻松连接并针对服务器质询进行身份验证。
解决方案:
将导出的 P12 文件包含在应用程序包中,并引用它以找到服务器正在寻找的正确客户端证书。这实际上是一种解决方法。硬编码是抓取P12文件的可靠方式。
实现:
有问题的方法是 NSURLConenction delegate
中的 willSendRequestForAuthenticationChallenge
。您需要考虑 NSURLAuthenticationMethodClientCertificate
质询类型才能处理服务器质询。在这里,我们实现了从嵌入式 P12 文件中提取正确证书身份的魔法。代码如下
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if ([challenge previousFailureCount] > 0) {
//this will cause an authentication failure
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
return;
}
//this is checking the server certificate
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType result;
//This takes the serverTrust object and checkes it against your keychain
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
//if we want to ignore invalid server for certificates, we just accept the server
if (kSPAllowInvalidServerCertificates) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
return;
} else if(result == kSecTrustResultProceed || result == kSecTrustResultConfirm || result == kSecTrustResultUnspecified) {
//When testing this against a trusted server I got kSecTrustResultUnspecified every time. But the other two match the description of a trusted server
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
return;
}
} else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
//this handles authenticating the client certificate
/*
What we need to do here is get the certificate and an an identity so we can do this:
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:myCerts persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
It's easy to load the certificate using the code in -installCertificate
It's more difficult to get the identity.
We can get it from a .p12 file, but you need a passphrase:
*/
NSString *p12Path = [[BundleManager bundleForCurrentSkin] pathForResource:kP12FileName ofType:@"p12"];
NSData *p12Data = [[NSData alloc] initWithContentsOfFile:p12Path];
CFStringRef password = CFSTR("PASSWORD");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef p12Items;
OSStatus result = SecPKCS12Import((CFDataRef)p12Data, optionsDictionary, &p12Items);
if(result == noErr) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(p12Items, 0);
SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);
SecCertificateRef certRef;
SecIdentityCopyCertificate(identityApp, &certRef);
SecCertificateRef certArray[1] = { certRef };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(certRef);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identityApp certificates:(NSArray *)myCerts persistence:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
} else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM) {
// For normal authentication based on username and password. This could be NTLM or Default.
DAVCredentials *cred = _parentSession.credentials;
NSURLCredential *credential = [NSURLCredential credentialWithUser:cred.username password:cred.password persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
//If everything fails, we cancel the challenge.
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
希望对你有帮助
关于ios - 在 Enterprise iOS 应用程序中使用来自 .mobileconfig 的客户端 SSL 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29754785/
Enterprise Architect 中的原型(prototype)“主文档”和“报告包”有什么区别?我将从多个模型文档生成一个文档,我想更好地组织它们以模仿生成的文档的结构。我认为创建“报告包”
Stackoverflow 上有几个问题询问 x ( Ruby/Drupal ) 技术是否已“企业就绪”。 我想问一下“企业就绪”是如何定义的。 有人创建了自己的 list 吗? 有人有测试的基准吗?
我要为我的 EA 项目创建一个脚本。为此,有必要创建一个新的“组”,您可以在该组中添加自己的脚本。 我在硬盘上找到的本地脚本。它们位于 EA-install-dir/Scritps 中。 但是我在哪里
我定义了一个带有操作的类,操作在几个时序图中使用。 有没有办法找出有多少序列图正在使用一个特定的操作? 最佳答案 如果我的理解正确,您应该能够执行以下操作: 在“项目浏览器”中展开您的类以查看操作 右
问题:我们的许多设计和架构文档都是在 Enterprise Architect 中创建和维护的。 ——无论好坏,就是这样。这些文档存储在我们的 subversion 存储库中——这对于创建和更新它们的
运行 Github Enterprise 2.18。有什么方法可以通过 API 确定用户处于休眠状态吗?我在任何地方都没有看到对它的具体调用... 最佳答案 为了回答你的问题...... Runnin
我有一个很大的遗留项目。 我加载了整个项目:Project->Source Code Engineering->Import Source Directory:(c++) & (path) 有没有一种
我的元素有 10 个或更多标记值,而不是一次删除一个,有没有办法同时删除它们? 最佳答案 正如 Uffe 指出的那样,您可以使用脚本来完成此操作。有关 EA 脚本的更多信息,请参阅 the EA Us
我有一些代码,我想创建Property Note var metric as EA.Element; metric = thePackage.Elements.AddNew("", "Text")
我正在尝试将一个图表中的用例链接到详细说明该用例的图表。 我正在做的是: 创建新的用例图(右键单击模型 -> 添加 -> 添加图) 将图表称为“测试” 在图表中添加用例(在图表中单击右键 -> 新建元
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我无法在“Enterprise Architect”(Sparx Systems)生成的类图中显示参数的名称。我正在尝试在下面添加一个操作 + delayFight(numberOfMinutes:
我正在阅读 Scylla 的文档,因为我们正计划从 DSE 迁移到本地 Scylla。然而,in their documentation ,他们说不支持 DSE SSTable 格式。 Here他们提
在模型搜索功能中似乎没有办法将结果限制为特定类型,例如类,节点等。有办法实现吗?我知道我可以制作一个 SQL 查询,但是无法找到正确的表名。 编辑 看来我可以做到以下几点 选择 *, Object_T
一些扩展 GitHub Enterprise 的服务需要足够新的版本。但作为 GH:E 的标准用户,我如何在不干扰管理员的情况下确定我的公司安装了哪个版本? 最佳答案 我正在为我们的 github 企
我正在阅读 Scylla 的文档,因为我们正计划从 DSE 迁移到本地 Scylla。然而,in their documentation ,他们说不支持 DSE SSTable 格式。 Here他们提
我有一个 54 页的 UML 图要打印。我想缩小图像大小或页面大小,以便打印不超过 12 页?有没有办法做到这一点? 最佳答案 开图 使用图->属性 在图表选项卡上,单击页面设置下的“高级...” 单
我有一个用例图,其中用例具有扩展关系。我想知道是否有任何 API 可用于了解将哪个扩展点设置为特定的扩展关系(在许多可以应用的扩展点中)。下面显示了用例图以及突出显示的扩展点。 最佳答案 假设这是一个
我正在尝试使用 Microsoft Enterprise Library 中的 DatabaseFactory 方法。 using Microsoft.Practices.EnterpriseLibr
有谁知道如何在使用 amazon ec2 M3.Xlarge 机器的集群中使用 Datastax 企业(使用 opscenter)? 当我尝试使用这些类型的实例(使用 ssd)时,出现以下错误: 启动
我是一名优秀的程序员,十分优秀!