Need help with NSURLCredential initWithTrust:
I have been beating my head against the wall for the last few hours and cannot find even a glimmer of a solution anywhere.
I am working on an app to learn how to work with JSON so I am just building a simple app that at first just returns a list of all of my repos on GitHub.
I am able to extract the JSON response from the data returned by NSURLConnection with no problem, unfortunately when I try to access anything that requires authentication the response is always {
message = "Not Found";
}
If I send a request to just get public information about my username I开发者_如何学Python get back the correct response with all the correct info so I know that I am successfully communicating with api.github.com.
First off to start the request I use:
-(IBAction)retriveRepos:(id)sender
{
responseData = [[NSMutableData data] retain];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://api.github.com/user/repos"]];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
When - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
gets called the authentication method comes back as NSURLAuthenticationMethodServerTrust
(which I find strange since I feel like I should be supplying a username and password to login). According to Apple's docs I need to create my NSURLCredential
with initWithTrust:
. I Googled for answers and finally found a few places that said to just take the serverTrust
from the protectionSpace
of the NSURLAuthenticationChallenge
that was passed in. Doing this shows no signs of having any effect at all, in fact it looks like my NSURLCredential
has pretty much nothing in it.
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
NSLog(@"challenge.protectionSpace.serverTrust: %@", challenge.protectionSpace.serverTrust); // This logs "challenge.protectionSpace.serverTrust: <SecTrust 0x10340b2e0 [0x7fff7cc12ea0]>"
NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
NSLog(@"credential: %@", credential); // Always logs something like "credential: <NSURLCredential: 0x1002d2f20>: (null)"
NSURLCredential *otherCredential = [[NSURLCredential alloc] initWithUser:@"user" password:@"password" persistence:NSURLCredentialPersistencePermanent];
NSLog(@"otherCredential: %@", otherCredential); // This logs otherCredential: <NSURLCredential: 0x1018d0840>: user"
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
I used more extensive logging as well that showed that credential
did in fact exist (at first I thought it hadn't been created at all) but that it had none of it's attributes set certificates: (null)
hasPassword: 0
identity: (null)
password: (null)
. I can only assume that the problem is in my authentication but I followed the examples I found to the letter. I am using the GM preview of Lion, so I guess it is possible I found a bug, or that there is some bug in the GitHub API, but given my skill level I find it much more likely that I am an idiot that is looking over the answer sitting right in front of me.
If anyone knows of a good guide that actually walks you through all the steps of authenticating (preferably in all the styles) rather than the severely lacking Apple URL loading guide that just says to use a method but doesn't say where the SecTrustRef
comes from it would be greatly appreciated.
NSURLAuthenticationMethodServerTrust
is what you will get back as it negotiates an SSL connection. It's giving you the opportunity to evaluate the trust of the server (or vice versa). Technote 2232 describes this in a bit of detail. Your delegate needs to handle it, the technote links to the source for the sample code Advanced URL Connections which should show you how to respond to that challenge.
Don't despair, if there is an HTTP authentication step coming from your server, you will see the delegate get that later.
精彩评论