NetworkLogger breaks client certificate authorization
davidblazek opened this issue · 8 comments
Steps to Reproduce the Problem
We're using a client certificate to authorize API calls. Using Alamofire session to provide client certificate in Alamofire SessionDelegate method like this works fine:
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
) {
switch challenge.protectionSpace.authenticationMethod {
case NSURLAuthenticationMethodClientCertificate:
guard let identity = pkiService.identity, let certificate = pkiService.certificate else {
return completionHandler(.performDefaultHandling, nil)
}
let urlCredential = URLCredential(
identity: identity,
certificates: [certificate],
persistence: .none
)
return completionHandler(.useCredential, urlCredential)
default:
return completionHandler(.performDefaultHandling, nil)
}
}
Using NetworkLogger.enableLogging(for: configuration)
breaks the delegate method above (method is not called). We've found in other related issues that this is a known behaviour and we should use setCanAuthenticateAgainstProtectionSpaceHandler
method as an alternative. Nevertheless providing client certificate via this method is not working.
Expected Behavior
Authentication flow using Alamofire session delegate method has these two steps:
- method is called with challenge
NSURLAuthenticationMethodServerTrust
, code above returns .performDefaultHandling - method is called again with challenge
NSURLAuthenticationMethodClientCertificate
, code above provides URLCredential with client certificate and all is fine
We expect the same flow in setCanAuthenticateAgainstProtectionSpaceHandler
Actual Behavior
Authentication flow using setCanAuthenticateAgainstProtectionSpaceHandler
has only one step (referring to the Instabug integration code below) :
- method is called with challenge
NSURLAuthenticationMethodServerTrust
- method is not called again with challenge
NSURLAuthenticationMethodClientCertificate
, therefore we're unable to provide client certificate
Note: no matter what we return from the first call (nil, empty URLCredential, challenge.proposedCredential), the second call never comes.
Instabug integration code
Here is our Instabug integration code snippet:
let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
NetworkLogger.setCanAuthenticateAgainstProtectionSpaceHandler { (urlProtectionSpace) -> Bool in
return true
}
NetworkLogger.setDidReceiveAuthenticationChallengeHandler { challenge in
switch challenge.protectionSpace.authenticationMethod {
case NSURLAuthenticationMethodClientCertificate:
guard let identity = pkiService.identity, let certificate = pkiService.certificate else {
return nil
}
return URLCredential(
identity: identity,
certificates: [certificate],
persistence: .none
)
default:
return nil
}
}
let alamoSession = Session(configuration: configuration)
SDK Version
11.0.2
iOS Version
iOS 15.5
Device Model
all
Other
Method setCanAuthenticateAgainstProtectionSpaceHandler
is deprecated without any reference to an alternative.
Hello @davidblazek,
I need your confirmation that the issue still happens if you totally remove setCanAuthenticateAgainstProtectionSpaceHandler
.
Regarding your question about an alternative API: There is no alternative, SSL pinning is handled automatically
Hi @ahmedsalah196 ,
I followed your advice and it actually helped, removing setCanAuthenticateAgainstProtectionSpaceHandler
causes that SessionDelegate
is called properly.
So to sum it up this snippet is problematic:
let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
NetworkLogger.setCanAuthenticateAgainstProtectionSpaceHandler { (urlProtectionSpace) -> Bool in
return true
}
let alamoSession = Session(configuration: configuration)
It can be fixed using your advice (removing setCanAuthenticateAgainstProtectionSpaceHandler
):
let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
let alamoSession = Session(configuration: configuration)
EDIT: Fix above caused that SessionDelegate
is called properly, but the network logs don't appear in Bug Reporting tool. I'll investigate it more.
@davidblazek Glad that the initial issue has been resolved and we'd love to assist you more with any other issues that you're facing
@ahmedsalah196 OK, let me correct my previous answer.
We're using Alamofire (along with Moya), we can provide client certificate using two ways:
- via Moya CredentialsPlugin (https://github.com/Moya/Moya/blob/master/docs/Authentication.md#basic-http-auth)
- via Alamofire SessionDelegate (like in the very first code snippet in this issue).
Both ways are working until we enable logging. After that both ways mentioned above break.
Using provided setDidReceiveAuthenticationChallengeHandler
method isn't helpful because
- removing
setCanAuthenticateAgainstProtectionSpaceHandler
causes thatsetDidReceiveAuthenticationChallengeHandler
isn't called at all - after returning
true
fromsetCanAuthenticateAgainstProtectionSpaceHandler
, closure insetDidReceiveAuthenticationChallengeHandler
is called but never withNSURLAuthenticationMethodClientCertificate
so we can't provide the client certificate.
So basically the original issue description still stands.
@davidblazek May you reach out to support@instabug.com to further investigate this in a debugging call?
This issue has been automatically marked as stale due to inactivity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale due to inactivity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically closed due to inactivity.