开发者

NSURLCredentialPersistencePermanent doesn't seem permanent?

I've been trying to solve this for some time now, but without success. Questions such as this one here or tuts on using authentication by apple and other blogs shed some light but not all.

My basic problem I'd like to solve is the following:

I'm successfully authenticating against my server by utilizing NSURLConnection its delegates and NSURLCredential with NSURLProtectionSpace and NSURLCredentialStorage. However even though I set the persistence of the NSURLCredential to NSURLCredentialPersistencePermanent I randomly get authentication challenges (401 and then 200) from my server after already having provided my credentials the first time - shouldn't that not be the case as NSURLCredentialPersistencePermanent lasts permanently? The random thing is what just doesn't make sense.

Sometimes it works and subsequent calls to the server return fine with 200. Then again it doesn't and 401 with 200 are returned. Mike Abdullah described the process nicely over here. So my first guess was that the process of returning 401 authenticating and getting a 200 is standard procedure and can't be eliminated. However sometimes I can eliminate the 401. So I seem to be missing out on something.

The requests I'm sending are some GETs and two POSTs. The thing is that one POST is uploading loads of data. When getting a 401 the data is still uploaded into nirvana after authentication it's uploaded again.

My fallback solution would be to prevent the data to be sent anyway when a 401 is received. I'm working on that right now, which seems tricky because sometimes 401 isn't returned as already mentioned before.

If this is in any way not comprehensible I'll add any info. My guess is either I'm using the whole NSURLCredential stuff in a wrong way or the way of authenticating by first getting a 401 and then a 200 is the way to go, thus can't be eliminated.

Excerpts from my code below:

loginCredential = [NSURLCredential credentialWithUser:@"foo" 
                                             password:@"bar"
                                          persistence:NSURLCredentialPersistencePermanent];

NSURLProtectionSpace *loginProtectionSpace = [[NSURLProtectionSpace alloc] initWithHost:@"foo.com"
                                                                                   port:8000 
                                                                               protocol:@"http" 
                                               开发者_StackOverflow                                   realm:nil 
                                                                   authenticationMethod:NSURLAuthenticationMethodBasic];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:loginCredential 
                                                    forProtectionSpace:loginProtectionSpace]; 
[loginProtectionSpace release];

loginCommunicator = [[LearnCommunicator alloc] initWithMethod:@"login-foo"     
                                                   credential:loginCredential];

With this setup the delegates of NSURLConnection get all called correctly

- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
{
    NSLog(@"connectionShouldUseCredentialStorage user: %@",[userCredential user]);
    return YES;
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    NSLog(@"canAuthenticateAgainstProtectionSpaceuser: %@",[userCredential user]);
    return YES;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSLog(@"didReceiveAuthenticationChallenge previousFailureCount: %i",[challenge previousFailureCount]);  
    if ([challenge previousFailureCount] == 0)
{
    NSLog(@"Challenging...");
    [[challenge sender] useCredential:userCredential forAuthenticationChallenge:challenge];
}
else
{
    NSLog(@"Username and password are incorrect");
    [[challenge sender] cancelAuthenticationChallenge:challenge];
}
}

Any input appreciated! Thx

EDIT UPDATE 01 This seems to be a known issue, which was already filed as bug report - a long time ago - but hasn't been resolved. NSURLConnection does not seem to support "Expect: 100-continue" header, which quite honestly is a major let down. I've been working hours on this issue just to find out now that I will have to rework everything. See the bug report for detailed info: http://openradar.appspot.com/5188833

EDIT UPDATE 02 My current workaround for this issue is to simply do an authentication right before going for the huge HTTP POST with movie data. As I have to upload some minor XML file aswell I'll use it's prior authentication for the movie upload. This still feels ugly to me, but I have to get things going... Any input/know how on this topic is still appreciated.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜