如何在Cocoa中使用WebView连接客户端证书? [英] How to connect with client certificate using a WebView in Cocoa?

查看:304
本文介绍了如何在Cocoa中使用WebView连接客户端证书?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试连接到需要客户端证书的服务器。
因此,浏览此服务器时发生的正常事件流程是Web浏览器(Safari和Chrome浏览器)提示用户选择证书并重试操作。



那么如何在Cocoa项目中的嵌入式WebView中实现呢?
到目前为止,我发现在 didFailProvisionalLoadWithError 方法中引发错误:

   - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
NSLog(@webView:didFailProvisionalLoadWithError:forFrame:);
NSLog(@error =%@,error);
}

错误确实是 error = Error Domain = NSURLErrorDomain Code = -1206 UserInfo = 0x1006a8030服务器myserver.xxx需要一个客户端证书。

但是如何显示一个对话框,以便用户可以从



A(已知) 问题与WebView组件是罪魁祸首
打开一个DTS支持票与苹果和解决方法。



编辑:
这里的解决方法从DTS(我不知道这是否仍然有效,因为它是3年前):


Magnus OK,一个机会看看这个,我知道发生了什么
。在我们开始谈论WebView之前,我需要带给你
速度在NSURLConnection使用的委托方法,这是
基本API用于实际加载数据从net。
NSURLConnection开始支持单一认证
委托回调,-connection:didReceiveAuthenticationChallenge :,到
它通过了各种身份验证挑战are
当时支持(用户名/密码风格的挑战)。在Mac
OS X 10.6(和iOS 3.0)NSURLConnection增强了支持两个
添加类型的身份验证挑战TLS连接:o
客户身份挑战
(NSURLAuthenticationMethodClientCertificate)委托
机会为给定的TLS连接选择客户机标识o
服务器信任挑战(NSURLAuthenticationMethodServerTrust),给予
代理机会覆盖服务器信任评估
给定的TLS连接出于兼容性原因,不是
可能在所有
情况下将这些挑战传递给委托,因此NSURLConnection引入了一个新的委托回调
-connection:canAuthenticateAgainstProtectionSpace :,允许代表们选择接受这些挑战。
* * *现在,让我们把它带回你的应用程序。正如我所提到的,WebView使用
NSURLConnection,并且对于每个连接,充当连接
委托。它拦截身份验证挑战,并将其传递给
其资源负载委托。这对老学校的
身份验证挑战很好,因为WebView得到的挑战没有
不得不做任何特殊的;但它失败TLS连接
身份验证挑战,因为代理必须选择这些
挑战。你真正需要的是WebView版本的
'canAuthenticateAgainstProtectionSpace'身份验证质询。
好​​吧,事实证明,这是实际实现。在通过WebView的开源查找
时,我发现有一个私人的
委托回调,
-webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource :,
这完全是你想要的。
http:// www .opensource.apple.com / source / WebKit / WebKit-7533.20.25 / mac / WebView / WebResourceLoadDelegatePrivate.h
如果实现该方法,您可以选择加入客户端身份
身份验证挑战并且基于该挑战呈现允许用户选择身份的用户
接口。我原型的
这在你的测试应用程序,它工作一个魅力。下面是我用于
的代码获取客户端身份挑战:
- (BOOL)webView:(WebView *)发送者资源:(id)标识符canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace
*)protectionSpace forDataSource: (WebDataSource *)dataSource {
NSLog(@%@,[protectionSpace authenticationMethod]);
return [[protectionSpace authenticationMethod] isEqual:NSURLAuthenticationMethodClientCertificate]; }这里是
代码我用来回应它:
- (void)webView:(WebView *)发送者资源:(id)标识符didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge
*)挑战fromDataSource: (webDataSource *)dataSource {
NSLog(@didReceiveAuthenticationChallenge);
NSString * authenticationMethod = [[challenge protectionSpace] authenticationMethod];
NSLog(@authenticationMethod =%@,authenticationMethod);

  [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge] ; } 

很明显,在一个真正的应用程序中,你需要显示一些UI, b用户选择了一个客户端身份,为其创建一个凭据
(+ [NSURLCredential credentialWithIdentity:certificates:persistence:])
然后将该凭证应用于该请求
(-useCredential: forAuthenticationChallenge :)。
* * *那么你从哪里开始呢?无论你做什么,你应该
提出一个错误对WebView获取
-webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:delegate回调发布在公共头。这是一个明显的,
和最烦人的,省略。 http://developer.apple.com/bugreporter/
一旦您提交了错误,请给我的错误编号,以便我可以
与此事件相关联。除此之外,前进的道路少了
。如果你创建一个非Mac App Store应用程序,我的建议
将是你实现
'canAuthenticateAgainstProtectionSpace'代理回调,因为我有
上面显示,生活。 OTOH,如果你创建一个
Mac App Store应用程序,其中使用私有API,包括委托
回调,严格禁止,生活变得更加棘手。让我
知道在这种情况下,我们可以讨论你的选择。分享和享用



I am trying to connect to a server that requires a client certificate. So the normal flow of events that happens when browsing to this server is that the web browser (both Safari and Chrome) prompts the user to select a certificate and retry the operation.

So how can I accomplish this in a embedded WebView in a Cocoa project? I have so far identified that the error is raised in the didFailProvisionalLoadWithError method:

- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
    NSLog(@"webView:didFailProvisionalLoadWithError:forFrame:");
    NSLog(@"    error = %@", error);
}

The error is indeed error = Error Domain=NSURLErrorDomain Code=-1206 UserInfo=0x1006a8030 "The server "myserver.xxx" requires a client certificate.
But how can I display a dialog so that the user can select a certificate from the keychain?

解决方案

Problem solved.

A (known) issue with the WebView component was the culprit. Opened up a DTS support ticket with Apple and got a workaround.

EDIT: Here's the workaround from DTS ( I have no idea if this is still valid, since it was 3 years ago):

Magnus OK, I've had a chance to look at this and I know what's going on. Before we start talking about WebView, I need to bring you up to speed on the delegate methods used by NSURLConnection, which is the underlying API used to actually load data off the 'net. NSURLConnection started out supporting a single authentication delegate callback, -connection:didReceiveAuthenticationChallenge:, to which it passed the various authentication challenges that were supported at that time (username/password-style challenges). In Mac OS X 10.6 (and iOS 3.0) NSURLConnection was enhanced to support two addition types of authentication challenges for TLS connections: o client identity challenges (NSURLAuthenticationMethodClientCertificate), giving the delegate the opportunity to select a client identity for a given TLS connection o server trust challenges (NSURLAuthenticationMethodServerTrust), giving the delegate the opportunity to override the server trust evaluation for a given TLS connection For compatibility reasons it was not possible to pass these challenges to the delegate under all circumstances, so NSURLConnection introduced a new delegate callback, -connection:canAuthenticateAgainstProtectionSpace:, that allows the delegate to opt in to these challenges. * * * Now, let's bring this back to your app. As I mentioned, WebView uses NSURLConnection and, for each connection, acts as the connection delegate. It intercepts authentication challenges and passes them to its resource load delegate. This works just fine for old school authentication challenges, because WebView gets the challenge without having to do anything special; but it fails for TLS connection authentication challenges, because the delegate has to opt in those challenges. What you really need is the WebView version of the 'canAuthenticateAgainstProtectionSpace' authentication challenge. Well, it turns out that this is actually implemented. In looking through the open source for WebView, I found that there's a private delegate callback, -webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:, that does exactly what you want. http://www.opensource.apple.com/source/WebKit/WebKit-7533.20.25/mac/WebView/WebResourceLoadDelegatePrivate.h If you implement that method you can opt in to the client identity authentication challenge and, based on that challenge, present a user interface that allows the user to select an identity. I prototyped this in your test app and it works a charm. Here's the code I used to get the client identity challenge: - (BOOL)webView:(WebView *)sender resource:(id)identifier canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace forDataSource:(WebDataSource *)dataSource { NSLog(@"%@", [protectionSpace authenticationMethod]); return [[protectionSpace authenticationMethod] isEqual:NSURLAuthenticationMethodClientCertificate]; } and here's the code I used to respond to it: - (void)webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource { NSLog(@"didReceiveAuthenticationChallenge"); NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod]; NSLog(@" authenticationMethod = %@", authenticationMethod);

 [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; }

Obviously in a real app you'd need to display some UI and then, once the user has selected a client identity, create a credential for it (+[NSURLCredential credentialWithIdentity:certificates:persistence:]) and then apply that credential to the chalenge (-useCredential:forAuthenticationChallenge:). * * * So where do you proceed from here? Regardless of what else you do, you should file a bug against WebView to get the -webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource: delegate callback published in the public headers. It's an obvious, and most annoying, omission. http://developer.apple.com/bugreporter/ Once you've filed a bug, please send me the bug number so that I can associate it with this incident. Beyond that, the way forward is less clear. If you're creating a non-Mac App Store app, my recommendation would be that you just implement the 'canAuthenticateAgainstProtectionSpace' delegate callback as I've shown above and move on with your life. OTOH, if you're creating a Mac App Store app, where the use of private API, including delegate callbacks, is strictly prohibited, life gets a lot trickier. Let me know in that case and we can discuss your options. Share and Enjoy

这篇关于如何在Cocoa中使用WebView连接客户端证书?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆