-1

I need to:

1) Authenticate against a forms authentication service

2) Save off cookie

3) Call web service with cookie

And I'm having a hell of a time trying to get this working. Has anyone had any luck with this? It seems like a very common operation.

Here's my code:

Hit auth URL and get the cookie:

- (IBAction)buttonGetCookieTap:(id)sender {
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.cookieURL];
    [request setHTTPShouldHandleCookies:YES];
    [request setHTTPMethod:@"POST"];
    self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- ( void )connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response
{
    NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
    NSDictionary *fields = [HTTPResponse allHeaderFields];
    self.cookie = [fields valueForKey:@"Set-Cookie"];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSURLCredential *credential = [NSURLCredential credentialWithUser:@"blah"
                                                             password:@"blah"
                                                          persistence:NSURLCredentialPersistenceForSession];
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

Now call auth service with the cookie:

- (IBAction)buttonCallServiceTap:(id)sender {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.dataURL];
    [request addValue:self.cookie forHTTPHeaderField:@"Cookie"];
    self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

Edit: Sorry, the problem I have is that I'm getting a barebones cookie back with just the session id but on the server end the cookie looks fine. Can anyone verify that there's nothing wrong with my cookie grabbing code? I've tried many variations of this and have the same problem. Thanks!

Travis M.
  • 10,930
  • 1
  • 56
  • 72

2 Answers2

1

I wrote an answer to a Stack Overflow question here, which provides sample code for examining your application's cookies. Someone else in that thread provided additional code for getting app-side cookie details. You might start there, to help troubleshoot authentication.

Community
  • 1
  • 1
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
1

I figured out how to do this, I had to build a soap message for the HTTP Body.

NSString *soapFormat = [NSString stringWithFormat:@"<?xml version='1.0' encoding='UTF-8'?>\n"
                            "<soap:Envelope\n"
                                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
                                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n"
                                "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
                                "<soap:Body>\n"
                                    "<Login xmlns=\"http://asp.net/ApplicationServices/v200\">\n"
                                        "<username>myusername</username>\n"
                                        "<password>mypassword</password>\n"
                                    "</Login>\n"
                                "</soap:Body>\n"
                            "</soap:Envelope>\n"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:self.authURL];
    [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"http://asp.net/ApplicationServices/v200/AuthenticationService/Login" forHTTPHeaderField:@"SOAPAction"];
    [request addValue:[NSString stringWithFormat:@"%d",[soapFormat length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[soapFormat dataUsingEncoding:NSUTF8StringEncoding]];
    self.authConnection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];

I can grab the cookie from didReceiveResponse

- ( void )connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response
{
    if (self.currentCookies == nil) {
        NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
        self.currentCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[HTTPResponse allHeaderFields] forURL:[NSURL URLWithString:@""]];
        NSLog(@"COOKIE: %@",((NSHTTPCookie*)[self.currentCookies objectAtIndex:1]).value);
    }
}

Then I use the cookie to get JSON data from the webservice.

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.dataURL];
    [request setHTTPMethod: @"GET"];
    NSString *cook = [NSString stringWithFormat:@".ASPXAUTH=%@",((NSHTTPCookie*)[self.currentCookies objectAtIndex:1]).value];
    [request addValue:cook forHTTPHeaderField:@"Cookie"];
    [request setHTTPShouldHandleCookies:NO];
    self.dataConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

I hope this helps someone who has a similar authentication system.

Travis M.
  • 10,930
  • 1
  • 56
  • 72