Alex Stone
Alex Stone

Reputation: 47328

iOS how to reset NSURLCredential for a given server or make my app forget it ever spoke to that server?

I'm looking for a way to implement being able to switch which NSURLCredential my web app is using to talk to a given server.

Is there a way for me to "reset" NSURLCredential ssl credentials for a given server trust and force the entire handshaking process to repeat using different set of credentials? In other words, I want my web app to forget it ever spoke to this server.

I think the code snippet below is what is retrieving the credential that I previously have evaluated.

- (void)customHTTPProtocol:(CustomHTTPProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{

NSURLCredential *   credential = nil;
SecTrustRef         trust;
NSURLProtectionSpace* protectionSpace = challenge.protectionSpace;
  if ([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            //this verifies that we are talking to a server that we trust by checking it's certificate


            // Extract the SecTrust object from the challenge, apply our trusted anchors to that
            // object, and then evaluate the trust.  If it's OK, create a credential and use
            // that to resolve the authentication challenge.  If anything goes wrong, resolve
            // the challenge with nil, which continues without a credential, which causes the
            // connection to fail.
            trust = [protectionSpace serverTrust];
            if (trust == NULL) {
                assert(NO);
            } else {
                // Just Ignore Self Signed Certs
                SecTrustResultType result;

                //This takes the serverTrust object and checkes it against your keychain
                SecTrustEvaluate(protectionSpace.serverTrust, &result);
                //if we want to ignore invalid server for certificates, we just accept the server
                credential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
                if(result == kSecTrustResultProceed ||
                          // result == kSecTrustResultConfirm || // Deprecated - Remove?
                          result == kSecTrustResultUnspecified) {

                    [challenge.sender useCredential:credential forAuthenticationChallenge: challenge];
                }
            }
            [protocol resolveAuthenticationChallenge:challenge withCredential:credential];
        }

//... more ways to resolve challenge
}

Upvotes: 0

Views: 572

Answers (1)

bllakjakk
bllakjakk

Reputation: 5065

I tried various way for achieving this but all in vein.

But 1 simple trick worked.

To force my web page to re-authenticate, I would add below at the end of the request url.

&r=1100910192 **(timestamp)**.

So instead of using the cached authenticated credential it infact re-authenticated.

In other cases just adding a # at the end of the request worked:

[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:8080/some.json#"]]

I hope it helped.

Upvotes: 3

Related Questions