如何做认证在UIWebView的正确? [英] How to do authentication in UIWebView properly?

查看:145
本文介绍了如何做认证在UIWebView的正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想支持HTTP在我UIWebView的基本身份验证。

I would like to support HTTP Basic Authentication in my UIWebView.

目前,我在取消请求

web视图:shouldStartLoadWithRequest:navigationType:然后处理它们在我自己的NSURLConnectionDelegate检查并在必要时提供凭据。然后我用 loadData:MIMETYPE:textEncodingName:BASEURL:来present HTML的Web视图。对于传递给委托的任何URL正常工作。

webView:shouldStartLoadWithRequest:navigationType: then handle them in my own NSURLConnectionDelegate to check for and provide credentials if needed. I then use loadData:MIMEType:textEncodingName:baseURL: to present HTML in the web view. That works fine for any URLs that are passed to the delegate.

我的问题是,委托绝不会为嵌入式元素,如图像,JavaScript或CSS文件。所以,如果我有一个HTML页面,它引用这与基本身份验证保护的图片时,图片不能正常加载。此外, web视图:didFinishLoad:不会被调用,因为Web视图不能完全加载页面。

My problem is that the delegate is never called for embedded elements, like images, JavaScript or CSS files. So if I have an HTML page which references an image which is protected with basic authentication, that image cannot be loaded properly. Additionally, webView:didFinishLoad: is never called, because the web view could not fully load the page.

我已经检查与兵马俑,在App Store上可用的第三方浏览器的情况下,它可以与形势完全应付自如。我认为这将有可能通过提供我自己的NSURLProtocol来解决这个问题,但似乎太复杂了。我缺少什么?

I have checked that case with Terra, a third-party browser available on the App Store, and it can fully cope with that situation. I think it would be possible to solve this by providing my own NSURLProtocol, but that seems too complicated. What am I missing?

推荐答案

尝试使用sharedCredentialStorage你需要验证所有域。

Try to use sharedCredentialStorage for all domains you need to authenticate.

下面是一个UIWebView工作的样本正是在IIS的Windows有只启用BasicAuthentication测试

Here is working sample for UIWebView it was tested against Windows IIS having only BasicAuthentication enabled

这是如何增加你的站点的凭据:

This is how to add your site credentials:

        NSString* login = @"MYDOMAIN\\myname";
        NSURLCredential *credential = [NSURLCredential credentialWithUser:login
                                                                 password:@"mypassword"
                                                              persistence:NSURLCredentialPersistenceForSession];

        NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
                                                 initWithHost:@"myhost"
                                                 port:80
                                                 protocol:@"http"
                                                 realm:@"myhost" // check your web site settigns or log messages of didReceiveAuthenticationChallenge
                                                 authenticationMethod:NSURLAuthenticationMethodDefault];


        [[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
        [protectionSpace release];    

您Webview是应该现在的工作,如果它不工作,下次使用code调试,特别是检查日志didReceiveAuthenticationChallenge的消息。

Your webView is supposed to work now, if it does not work use next code to debug, especially check log messages of didReceiveAuthenticationChallenge.

    #import "TheSplitAppDelegate.h"
    #import "RootViewController.h"

    @implementation TheSplitAppDelegate

    @synthesize window = _window;
    @synthesize splitViewController = _splitViewController;
    @synthesize rootViewController = _rootViewController;
    @synthesize detailViewController = _detailViewController;

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // Override point for customization after application launch.
        // Add the split view controller's view to the window and display.
        self.window.rootViewController = self.splitViewController;
        [self.window makeKeyAndVisible];

        NSLog(@"CONNECTION: Add credentials");

        NSString* login = @"MYDOMAIN\\myname";
        NSURLCredential *credential = [NSURLCredential credentialWithUser:login
                                                                 password:@"mypassword"
                                                              persistence:NSURLCredentialPersistenceForSession];

        NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
                                                 initWithHost:@"myhost"
                                                 port:80
                                                 protocol:@"http"
                                                 realm:@"myhost" // check your web site settigns or log messages of didReceiveAuthenticationChallenge
                                                 authenticationMethod:NSURLAuthenticationMethodDefault];


        [[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
        [protectionSpace release];    

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://myhost/index.html"]
                                                               cachePolicy:NSURLRequestReloadIgnoringCacheData
                                                           timeoutInterval:12
                                        ];

        NSLog(@"CONNECTION: Run request");
        [[NSURLConnection alloc] initWithRequest:request delegate:self];

        return YES;
    }

    - (void)applicationWillResignActive:(UIApplication *)application
    {

    }

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {

    }

    - (void)applicationWillEnterForeground:(UIApplication *)application
    {

    }

    - (void)applicationDidBecomeActive:(UIApplication *)application
    {

    }

    - (void)applicationWillTerminate:(UIApplication *)application
    {

    }

    - (void)dealloc
    {
        [_window release];
        [_splitViewController release];
        [_rootViewController release];
        [_detailViewController release];
        [super dealloc];
    }

    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
    {
        NSLog(@"CONNECTION: got auth challange");
        NSString* message = [NSString stringWithFormat:@"CONNECTION: cred cout = %i", [[[NSURLCredentialStorage sharedCredentialStorage] allCredentials] count]];
        NSLog(message);
        NSLog([connection description]);

        NSLog([NSString stringWithFormat:@"CONNECTION: host = %@", [[challenge protectionSpace] host]]);
        NSLog([NSString stringWithFormat:@"CONNECTION: port = %i", [[challenge protectionSpace] port]]);
        NSLog([NSString stringWithFormat:@"CONNECTION: protocol = %@", [[challenge protectionSpace] protocol]]);
        NSLog([NSString stringWithFormat:@"CONNECTION: realm = %@", [[challenge protectionSpace] realm]]);
        NSLog([NSString stringWithFormat:@"CONNECTION: authenticationMethod = %@", [[challenge protectionSpace] authenticationMethod]]);
    }

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
        // release the connection, and the data object
        [connection release];

        // inform the user
        NSLog(@"CONNECTION: failed! Error - %@ %@",
              [error localizedDescription],
              [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
    } 

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
    {
        NSLog(@"CONNECTION: received response via nsurlconnection");
    }

    - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
    {
        NSLog(@"CONNECTION: USE!");
        return YES;
    }


    @end

有关的WebView验证的最终解决方案是基于自定义协议的实现。所有协议注册为一个栈,所以如果你重新定义HTTP协议,将拦截从web视图的所有请求,所以你必须检查与传入请求assotiated属性,并将其重新包装成新的要求,并通过自己的连接再次发送。既然你在堆栈中,您的要求immidiatly再来给你,你必须忽略它。如此这般下来协议栈,真正的HTTP协议的实现,因为你的请求不athenticated你会得到authenticaiton请求。而authenticaiton后,你会得到从服务器上真实的反应,让你重新包装响应和回复原始请求从web视图收到的,就是这样。

The final solution for WebView authentication was based on custom protocol implementation. All protocols registered as a stack, so if you redefine HTTP protocol it would intercept all requests coming from webView, so you have to check attributes assotiated with incoming request and repack it into new request and send it again via your own connection. Since you are in stack, your request immidiatly comes to you again and you have to ignore it. So it goes down protocol stack to real HTTP protocol implementation, since your request is not athenticated you'll get authenticaiton request. And after authenticaiton you'll get a real response from server, so you repack response and reply to original request received from webView and that's it.

不要;吨尝试创建新的请求或响应机构,你必须重新发送刚才他们。最后code将是code的aproximetly 30-40行,这是很简单,但需要大量的debuging和家具测试产品的。

Don;t try to create new requests or responses bodies, you have to just resend them. The final code would be aproximetly 30-40 lines of code and it is quite simple, but requires a lot of debuging and tetsing.

Unfortunatlly我不能提供code在这里,因为我分配到不同的项目了,我只想说,我的职务是错误的方式,它stucks当用户更改密码。

Unfortunatlly I cannot provide code here, since I am assigned to different project already, I just wanted to say that my post is wrong way, it stucks when user changes password.

这篇关于如何做认证在UIWebView的正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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