iosasp.netcookiesnsmutableurlrequest.aspxauth

How to correctly include .ASPXAUTH and ASP.NET_SessionId cookies with NSMutableURLRequest


I've been at this problem for a few days. My app needs to login to an ASP.NET (version: 4.0.30319, MVC version: 3.0) server and then post via a NSMutableURLRequest to a restricted page (a page that requires you to be logged in to access).

Currently I can, successfully, login to the website. To login I use this code:

NSString *post =[[NSString alloc] initWithFormat:@"LogInEmail=%@&Password=%@",@"username@website.com",@"password"];
NSURL *url=[NSURL URLWithString:@"http://www.website.com/LogIn"];

NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *responseMeta = nil;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseMeta error:&error];

I can check and see that both an ASP.NET_SessionId and .ASPXAUTH cookie, for that website, can be found in the sharedHTTPCookieStorage. I understand that both of these need to be sent with a request if I want to "be logged in".

The code for checking the cookies is here:

NSArray *cookiesForURL = [cookieJar cookiesForURL: [NSURL URLWithString: @"http://www.example.com"]];

for (cookie in cookiesForURL)
{
    if([cookie.name compare:@"ASP.NET_SessionId"] == NSOrderedSame)
    {
        ASPdotNET_SessionId = [cookie value];
        NSLog(@"ASP.NET_SessionId: %@"  , ASPdotNET_SessionId);
    }
    if([cookie.name compare:@".ASPXAUTH"] == NSOrderedSame)
    {
        dotASPXAUTH = [cookie value];
        NSLog(@".ASPXAUTH: %@"          , dotASPXAUTH);
    }
}

To clear the cookies use this:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *each in [[cookieStorage cookiesForURL:[NSURL URLWithString:@"http://www.example.com"]] copy]) {
    [cookieStorage deleteCookie:each];
}

I tried posting to the restricted page by modifying NSString *post and NSUrl *url and using the same code above.

NSString *post =[[NSString alloc] initWithFormat:[MessageId stringByAppendingString:@"=%@"],Comment];
NSURL *url=[NSURL URLWithString:@"https://www.website.com/message

This is unsuccessful. I assume because I neglected the cookies in some way. I have tried adding in this code just under [request setHTTPMethod:@"POST"];:

[request addValue:ASPdotNET_SessionId forHTTPHeaderField:@"Cookie"];

and/or:

[request addValue:dotASPXAUTH forHTTPHeaderField:@"Cookie"];

where ASPdotNET_SessionId and dotASPXAUTH are the cookie values retrieved from the sharedHTTPCookieStorage.

I feel like this is really simple, any help?


Solution

  • After more testing, it appears I was wrong when I thought I had been unsuccessful with the authentication. It appears that either NSURLConnection or NSMutableURLRequest handle the cookies for me and I do not need to retrieve from the sharedHTTPCookieStorageor set them with my request.

    Further if someone were to manually send the cookies they should be of at least this format and not just the pure value because ASP.NET expects the cookies to be in a certain format:

    [request setValue:[NSString stringWithFormat:@"ASP.NET_SessionId=%@", ASPdotNET_SessionId] forHTTPHeaderField:@"Cookie"];
    [request setValue:[NSString stringWithFormat:@".ASPXAUTH=%@", dotASPXAUTH] forHTTPHeaderField:@"Cookie"];
    

    or possibly this if the above does not work:

    [request setValue:[[NSString stringWithFormat:@"ASP.NET_SessionId=%@", ASPdotNET_SessionId] stringByAppendingString:@"; path=/; HttpOnly"] forHTTPHeaderField:@"Cookie"];
    [request setValue:[[NSString stringWithFormat:@".ASPXAUTH=%@", dotASPXAUTH] stringByAppendingString:@"; path=/; HttpOnly"] forHTTPHeaderField:@"Cookie"];
    

    Where ASPdotNET_SessionId is the 24 char Session ID and dotASPXAUTH is the 448 char authentication string.