- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试在我正在开发的 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/
我打算创建一个应用程序来同步 Exchange ActiveSync (EAS) 和我自己的数据库之间的电子邮件、日历和联系人。几个问题: 是否有任何 EAS 库或包装器? (最好使用 Java) 许
我正在编写一个跨平台的 C++ 应用程序,它需要连接到 Exchange 服务器并使用 ActiveSync 下载邮件。 是否有可用于 ActiveSync 的库(最好是开源库)? 我无法使用 Win
我正在为移动设备管理开发一个桌面应用程序,用于监控 Exchange Server 事件。具体来说,我想知道哪些设备试图连接到 Exchange 事件同步,即“谁试图将移动设备连接到他们的邮箱”。检测
有谁知道有什么好的库可以将 Exchange ActiveSync 协议(protocol)实现到 C# 应用程序中,以便我可以将电子邮件与应用程序同步到服务器(例如 m.google.com)? 最
有人熟悉 Exchange ActiveSync 库或 python 开源客户端吗?我已经完成了初步搜索,但收效甚微。我看过 C# 的一些示例,但我想在尝试移植任何东西之前我会在这里询问一下。 如果你
我在 WindowsCE 5.0 设备上使用 CompactFramework 3.5 来构建一个应用程序,该应用程序应该使用主动同步的连接来获取一些数据。 我如何检测移动设备是否在通讯座中并具有事件
我正在尝试构建一个简单的 Exchange ActiveSync 客户端。 我使用一个简单的 Python 脚本,在连接到 Exchange 2010 SP1 时发送初始同步电子邮件命令。 在请求正文
我的公司正在开发一个桌面和移动电子邮件客户端的项目,该客户端可以连接到不同的邮件服务器,用户或服务器管理员只需进行最少的配置。由于我们想要支持 Microsoft Exchange,因此我们似乎必须在
我正在使用 .NET Compact Framework 3.5 和 VS2008 开发一个 Windows Mobile 应用程序,并使用 Device Emulator V3 在 Win7 上进行
我正在尝试在我正在开发的 ActiveSync 客户端中实现证书身份验证。使用证书身份验证的代码可能有效,但截至目前,服务器,或者更准确地说,iOS 库对服务器响应的解释,对我来说似乎是不正确的。这是
我有一个项目,我需要复制在 PDA 中找到的文件(在我的情况下,它是一个 MC3000,如果这有什么不同的话)。我安装了 ActiveSync,它为我创建了同步文件夹就好了。但是,我希望能够不仅在其
检测 PC 是否安装了 Microsoft ActiveSync 的最佳/最可靠方法是什么?我的 PC 程序使用 RAPI 从设备中获取文件,如果未安装它,则会出现无法找到 RAPI.dll 的错误。
我们有一个应用程序需要与邮件进行交互。为此,我们的客户希望我们:- 检索用户在手机通用参数上输入的Activesync参数。- 使用这些 activesync 参数以静默方式发送邮件。- 能够阅读和解
我试错了几天,查看了交易所日志,在网上搜索了很多遍,至今无法解决这个问题。 我正在我的 iOS 应用程序中实现 ActiveSync 功能,到目前为止已经成功地编写了自动发现过程和 HTTP OPTI
有没有办法在 Android 中使用 Activity 同步协议(protocol)在 Exchange 服务器中搜索邮件,我尝试了很多方法,但它适用于全局地址查找,但不适用于邮件。任何人都可以提供它
从 Froyo (Android 2.2) 开始,Google 的 Android 操作系统就支持使用 ActiveSync 协议(protocol)同步 Microsoft Exchange 帐户。
我在 ActiveSync 上使用 TCP/IP 从 Windows CE 设备连接到 Windows XP 桌面。WinSock connect() 函数总是成功,无论桌面服务器应用程序是否实际运行
我正在开发一个管理联系人信息的桌面应用程序,我希望能够将其与 Windows Mobile 设备上的联系人列表同步。我需要了解哪些 namespace /API 才能执行此操作?我更喜欢 .NET c
根据 Microsofts documentation,我正在尝试编写一个程序,该程序将在连接 Windows Mobile 设备时运行。为此,我们必须: If you want your RAPI
我遇到了一种情况,我想要连接到一个电子邮件服务器,该服务器唯一公开的邮件/日历服务是 Activesync(它是一个 Exchange 服务器)。唯一暴露的网络界面是“OWA light”,这很可怕。
我是一名优秀的程序员,十分优秀!