AzureAD / microsoft-authentication-library-common-for-android

Common code used by both the Active Directory Authentication Library (ADAL) and the Microsoft Authentication Library (MSAL)
MIT License
41 stars 35 forks source link

PasskeyFidoChallengeHandler and associated classes #2146

Closed melissaahn closed 10 months ago

melissaahn commented 1 year ago

Summary

The majority of this PR consists of new classes and their associated unit tests. The new classes are wired up, but are guarded by a flag until the passkey feature release. It also includes a new dependency which allows us to use lifecycle coroutine scopes, as well as a test dependency (JSONAssert) which allows for cleaner comparisions between JSON objects in Junit tests.

The general steps after user clicks "use a passkey/security key" (or some string like that) in the WebView:

  1. Server sends a redirect uri, which our AzureActiveDirectoryWebViewClient will identify as a passkey protocol redirect uri.
  2. We first try to create the challenge handler. Then we try to create the challenge from the query string parameters in the uri.
  3. We will process the challenge by creating a Json string request in a particular WebAuthn format and invoking the Fido API (which will be Credential Manager, but that implementation will come in the last PR for this feature), which will guide the user through choosing a passkey and providing their biometrics/system PIN.
  4. If successful, we will receive the results back as a JSON string response, which we will parse out to get the object that we need to return to the server. If not successful (exception thrown), we will get the error message details. (Future work will involve putting the exception in a certain format that the server expects; this format is in discussion).
  5. The results will be sent back to the server via an Assertion header.
  6. User will either be logged in, or they will see an error message and will be asked to try again.

AuthFidoChallengeHandler

AuthFidoChallengeHandler takes in FidoChallenge into processChallenge and handles getting the assertion from the FidoManager, which is run in a lifecycle coroutine scope. The class also has a respondToChallenge method which handles responding back to the server with the expected header values. Unit tests were created for AuthFidoChallengeHandler using test implementations of IFidoManager and WebView. Additional unit tests were created for WebAuthnJsonUtil.

LifecycleScope

We'll need to run the CredMan API logic in a coroutine scope, so I chose to use a Lifecycle scope so that the passkey logic is tied to the lifecycle of the WebView. For more information: https://developer.android.com/topic/libraries/architecture/coroutines#lifecyclescope The dependencies added are androidx.lifecycle:lifecycle-runtime-ktx and androidx.lifecycle:lifecycle-runtime-testing. The addition of the lifecycle dependency will not bring us above the current limit we've set for dependency size for common (10.57 MB -> 10.66 MB, from dependenciesSizeCheck).

Wiring up in AzureActiveDirectoryWebViewClient

The passkey protocol request will come in as a redirect uri. We'll identify the uri in the handleUrl method and create the appropriate classes (challenge handler, challenge, etc.) to handle the challenge and respond back to the server.

Upcoming Work