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);
}
}