OAuth 2 bearer Authorization header

rckoenes picture rckoenes · Aug 23, 2012 · Viewed 20.8k times · Source

With an update to the client's API the HTTPBasicAuthication method has been replace with a OAuth2 Bearer Authorization header.

With the old API I would do the following:

NSURLCredential *credential = [NSURLCredential credentialWithUser:self.account.username 
                                                         password:self.account.token 
                                                      persistence:NSURLCredentialPersistenceForSession];

NSURLProtectionSpace *space = [[NSURLProtectionSpace alloc] initWithHost:kAPIHost
                                                                    port:443
                                                                protocol:NSURLProtectionSpaceHTTPS
                                                                   realm:@"my-api"
                                                    authenticationMethod:NSURLAuthenticationMethodHTTPBasic];

But this will not work with the Bearer header.

Now normally I would just add the header my self by adding it like so:

NSString *authorization = [NSString stringWithFormat:@"Bearer %@",self.account.token];
[urlRequest setValue:authorization forHTTPHeaderField:@"Authorization"];

But the problem with this solutions is that the API redirect most of the calls to other URLs, this has to do with security. After the NSURLRequest gets redirected the Authorization header is removed from the request and since I'm unable to add the Bearer method to the NSURLCredentialStorage it can't authenticate any more after being redirected.

What would be a good solutions? I can only think to catch the redirect and modify the NSURLRequest so it does include the Bearer header. But how?

Answer

rckoenes picture rckoenes · Aug 24, 2012

Well after much research I found out that I will just have to replace the NSURLRequest when a call is redirected.

Not as nice as I would like it to be, but is does work.

I used AFNetworking and added the redirect block, then check wether the Authorization header is still set if not I create a new NSMutableURLRequest and set all the properties to match the old request (I know I could have just created a mutable copy):

[requestOperation setRedirectResponseBlock:^NSURLRequest *(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse) {

    if ([request.allHTTPHeaderFields objectForKey:@"Authorization"] != nil) {
        return request;
    }

    NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:request.URL cachePolicy:request.cachePolicy timeoutInterval:request.timeoutInterval];
    NSString *authValue = [NSString stringWithFormat:@"Bearer %@", self.account.token];
    [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"];

    return  urlRequest;

}];