Clarification Needed on Sending AuthenticatorAssertionResponse Over Network in iOS Client
nashysolutions opened this issue · 2 comments
Hello,
I am currently integrating WebAuthn authentication into an iOS client by leveraging the public model layer of the webauthn-swift library. During this process, I have tailored the library to fit the specific needs of my application, particularly for transmitting AuthenticatorAssertionResponse
to a server, which may not align entirely with the library's original design intentions.
During the implementation, I encountered an issue regarding the structure of AuthenticatorAssertionResponse
, specifically its use of [UInt8]
arrays for properties instead of base64URLEncoded strings.
Context
The AuthenticatorAssertionResponse
structure, which is a property on AuthenticationCredential
is designed with properties as [UInt8]
arrays, which seems ideal for internal processing and verification of data received from an authenticator. However, the final step of the WebAuthn authentication process requires sending the AuthenticatorAssertionResponse
to a server in a JSON payload.
Issue
Given the current structure, there's a challenge in preparing the AuthenticatorAssertionResponse
for transmission over the network, as the properties need to be base64URLEncoded strings within the JSON payload. This requirement seems to contrast with the intended use of the structure, which is designed more for receiving and processing data than for network transmission.
Questions and Suggestions
Could you provide guidance on the recommended way to handle AuthenticatorAssertionResponse
for network transmission in an iOS client context? Should I just send the payload as [String: Any]
?
I believe clarification or enhancement in this area could greatly benefit developers implementing WebAuthn on iOS platforms, ensuring both the integrity of the authentication process and ease of integration.
Thank you for your time and the excellent work on the webauthn-swift library. I look forward to your insights and recommendations.
// let clientDataJSON: URLEncodedBase64 = passkeyAssertion.rawClientDataJSON.base64URLEncodedString()
// let authenticatorData: URLEncodedBase64 = passkeyAssertion.rawAuthenticatorData.base64URLEncodedString()
// let signature: URLEncodedBase64 = passkeyAssertion.signature.base64URLEncodedString()
// let userHandle: URLEncodedBase64 = passkeyAssertion.userID.base64URLEncodedString()
// let response = AuthenticatorAssertionResponse(
// clientDataJSON: clientDataJSON.decodedBytes ?? [],
// authenticatorData: authenticatorData.decodedBytes ?? [],
// signature: signature.decodedBytes ?? [],
// userHandle: userHandle.decodedBytes ?? [],
// attestationObject: nil
// )
// let id: URLEncodedBase64 = passkeyAssertion.credentialID.base64URLEncodedString()
// let rawID: URLEncodedBase64 = passkeyAssertion.credentialID.base64URLEncodedString()
// let credential = AuthenticationCredential(
// id: id,
// rawID: rawID.decodedBytes ?? [],
// response: response,
// authenticatorAttachment: nil,
// type: "public-key"
// )
let clientDataJSONBase64UrlString = passkeyAssertion.rawClientDataJSON.base64URLEncodedString().asString()
let authenticatorDataBase64UrlString = passkeyAssertion.rawAuthenticatorData.base64URLEncodedString().asString()
let signatureBase64UrlString = passkeyAssertion.signature.base64URLEncodedString().asString()
let userHandleBase64UrlString = passkeyAssertion.userID?.base64URLEncodedString().asString() ?? ""
let response: [String: Any] = [
"clientDataJSON": clientDataJSONBase64UrlString,
"authenticatorData": authenticatorDataBase64UrlString,
"signature": signatureBase64UrlString,
"userHandle": userHandleBase64UrlString
]
let id = passkeyAssertion.credentialID.base64URLEncodedString().asString()
let rawID = id
let payload: [String: Any] = [
"id" : id,
"rawID" : rawID,
"response" : response,
"type" : "public-key"
]
You are probably better off creating your own codable types based off what your server implementation expects, and transform them on the server end as necessary. That said, I have also embarked on implementing a full client implementation (not necessarily to interface with AuthenticationServices though) that you may be able to cherry pick from: main...dimitribouniol:webauthn-swift:dimitri/client (currently, I've only tacked the registration half)
You are probably better off creating your own codable types based off what your server implementation expects, and transform them on the server end as necessary. That said, I have also embarked on implementing a full client implementation (not necessarily to interface with AuthenticationServices though) that you may be able to cherry pick from: main...dimitribouniol:webauthn-swift:dimitri/client (currently, I've only tacked the registration half)
Thank you