NSUrlcredential object's user, password fields are null despite of 'Proceed' result of Trust evaluation (SecTrustEvaluate)

We are trying to communicate with an OAuth server for generating OAuth token for authentication.

Cloudflare is in between us(client) and server.


I followed Technical note 2232 from Apple. Also referred to documentation of Apple.


As written in below code we create NSUrlCredential object from server trust object of challenge . We are getting NSUrlCredential fields (user, password) as null despite of 'Proceed' result of SecTrustEvaluate. It has HasPassword field as false.


In DidReceiveData callback of NSUrlSessionDataDelegate, we receive data with error "invalid_grant","error_description":"Invalid username and password combination".


Finally in DidCompleteWithError we get a response with http status code 401. This happens on iOS11 and iOS12 as well .


What extra thing we need to do with sec trust object (challenge.ProtectionSpace.ServerSecTrust) to get credentials from it or we need to make changes at server end.

We are working on app built with Xamarin.iOS.


public override void DidReceiveChallenge(NSUrlSession session, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)

{


if (challenge.ProtectionSpace.AuthenticationMethod.Equals("NSURLAuthenticationMethodServerTrust"))

{



if (challenge.ProtectionSpace.Host.Equals("Our domain")

{

if (challenge.ProtectionSpace.ServerSecTrust == null)

{

completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, null);

}

else

{

NSData data = challenge.ProtectionSpace.ServerSecTrust.GetExceptions();

bool added = challenge.ProtectionSpace.ServerSecTrust.SetExceptions(data);



NSError error;

bool passed = challenge.ProtectionSpace.ServerSecTrust.Evaluate(out error);

SecTrustResult sResult = challenge.ProtectionSpace.ServerSecTrust.GetTrustResult();

if (sResult == SecTrustResult.Proceed)

{

NSUrlCredential urlcredential = NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust);

completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, urlcredential);

}

else

{

completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null);

}

}

}

else

{

completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, null);

}



}

Accepted Reply

You have misunderstood the semantics of the

NSURLAuthenticationMethodServerTrust
authentication challenge. This has nothing to do with OAuth and everything to do with TLS server trust evaluation. TLS authentication challenges (this one and
NSURLAuthenticationMethodClientCertificate
) never have password information.

Finally in DidCompleteWithError we get a response with http status code 401.

This 401 error is coming from your server, indicating that your request was able to make it to the server and the response made it back to your client (thus TLS is working just fine). I’m not sure why the server is failing your request, but I have put general guidance on that topic in my Debugging HTTP Server-Side Errors article.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

You have misunderstood the semantics of the

NSURLAuthenticationMethodServerTrust
authentication challenge. This has nothing to do with OAuth and everything to do with TLS server trust evaluation. TLS authentication challenges (this one and
NSURLAuthenticationMethodClientCertificate
) never have password information.

Finally in DidCompleteWithError we get a response with http status code 401.

This 401 error is coming from your server, indicating that your request was able to make it to the server and the response made it back to your client (thus TLS is working just fine). I’m not sure why the server is failing your request, but I have put general guidance on that topic in my Debugging HTTP Server-Side Errors article.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Eskimo.


That error was coming from my server. Basically it was a POST request . I started sending Body in different content type format and then it worked.


Best Regards,


Amol Sarmalkar