Skip to content

Commit 9afc8ef

Browse files
authored
breaking: removed the deprecated MFA APIs (#947)
1 parent 962addf commit 9afc8ef

File tree

5 files changed

+13
-423
lines changed

5 files changed

+13
-423
lines changed

EXAMPLES.md

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@
1515
- [DPoP](#dpop)
1616
- [Authentication API](#authentication-api)
1717
- [Login with database connection](#login-with-database-connection)
18-
- [Login using MFA with One Time Password code](#login-using-mfa-with-one-time-password-code)
1918
- [MFA Flexible Factors Grant](#mfa-flexible-factors-grant)
2019
- [Understanding the mfa_required Error Payload](#understanding-the-mfa_required-error-payload)
2120
- [Handling MFA Required Errors](#handling-mfa-required-errors)
2221
- [Getting Available Authenticators](#getting-available-authenticators)
2322
- [Enrolling New Authenticators](#enrolling-new-authenticators)
2423
- [Challenging an Authenticator](#challenging-an-authenticator)
25-
- [Verifying MFA](#verifying-mfa)
2624
- [MFA Client Errors](#mfa-client-errors)
2725
- [Passwordless Login](#passwordless-login)
2826
- [Step 1: Request the code](#step-1-request-the-code)
@@ -52,11 +50,6 @@
5250
- [Handling Credentials Manager exceptions](#handling-credentials-manager-exceptions)
5351
- [Passkeys](#passkeys)
5452
- [Bot Protection](#bot-protection)
55-
- [Management API](#management-api)
56-
- [Link users](#link-users)
57-
- [Unlink users](#unlink-users)
58-
- [Get User Profile](#get-user-profile)
59-
- [Update User Metadata](#update-user-metadata)
6053
- [Token Validation](#token-validation)
6154
- [Organizations](#organizations)
6255
- [Log in to an organization](#log-in-to-an-organization)
@@ -404,62 +397,6 @@ authentication
404397

405398
> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced.
406399
407-
### Login using MFA with One Time Password code
408-
409-
This call requires the client to have the *MFA* Client Grant Type enabled. Check [this article](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it.
410-
411-
When you sign in to a multifactor authentication enabled connection using the `login` method, you receive an error standing that MFA is required for that user along with an `mfa_token` value. Use this value to call `loginWithOTP` and complete the MFA flow passing the One Time Password from the enrolled MFA code generator app.
412-
413-
```kotlin
414-
authentication
415-
.loginWithOTP("the mfa token", "123456")
416-
.validateClaims() //mandatory
417-
.start(object: Callback<Credentials, AuthenticationException> {
418-
override fun onFailure(exception: AuthenticationException) { }
419-
420-
override fun onSuccess(credentials: Credentials) { }
421-
})
422-
```
423-
424-
<details>
425-
<summary>Using coroutines</summary>
426-
427-
```kotlin
428-
try {
429-
val credentials = authentication
430-
.loginWithOTP("the mfa token", "123456")
431-
.validateClaims()
432-
.await()
433-
println(credentials)
434-
} catch (e: AuthenticationException) {
435-
e.printStacktrace()
436-
}
437-
```
438-
</details>
439-
440-
<details>
441-
<summary>Using Java</summary>
442-
443-
```java
444-
authentication
445-
.loginWithOTP("the mfa token", "123456")
446-
.validateClaims() //mandatory
447-
.start(new Callback<Credentials, AuthenticationException>() {
448-
@Override
449-
public void onSuccess(@Nullable Credentials payload) {
450-
//Logged in!
451-
}
452-
453-
@Override
454-
public void onFailure(@NonNull AuthenticationException error) {
455-
//Error!
456-
}
457-
});
458-
```
459-
</details>
460-
461-
> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced.
462-
463400
### MFA Flexible Factors Grant
464401

465402
> [!IMPORTANT]

V4_MIGRATION_GUIDE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ v4 of the Auth0 Android SDK includes significant build toolchain updates, update
1414
+ [Kotlin Version](#kotlin-version)
1515
- [**Breaking Changes**](#breaking-changes)
1616
+ [Classes Removed](#classes-removed)
17+
+ [Deprecated MFA Methods Removed from AuthenticationAPIClient](#deprecated-mfa-methods-removed-from-authenticationapiclient)
1718
+ [DPoP Configuration Moved to Builder](#dpop-configuration-moved-to-builder)
1819
+ [SSOCredentials.expiresIn Renamed to expiresAt](#ssocredentialsexpiresin-renamed-to-expiresat)
1920
- [**Default Values Changed**](#default-values-changed)
@@ -110,6 +111,17 @@ buildscript {
110111
2. Call that endpoint from your app, passing the user's access token as a `Bearer` token in the `Authorization` header.
111112
3. On your backend, obtain a machine-to-machine token via the Client Credentials flow and use it to call the Management API with the precise scopes required.
112113

114+
### Deprecated MFA Methods Removed from AuthenticationAPIClient
115+
116+
The following MFA methods have been removed from `AuthenticationAPIClient`. They were deprecated in v3 in favor of the `MfaApiClient` class APIs.
117+
118+
- `loginWithOTP(mfaToken, otp)`
119+
- `loginWithOOB(mfaToken, oobCode, bindingCode)`
120+
- `loginWithRecoveryCode(mfaToken, recoveryCode)`
121+
- `multifactorChallenge(mfaToken, challengeType, authenticatorId)`
122+
123+
Use `AuthenticationAPIClient.mfaClient(mfaToken)` to obtain a `MfaApiClient` instance and handle MFA flows using the new APIs. See the [MFA Flexible Factors Grant](EXAMPLES.md#mfa-flexible-factors-grant) section in `EXAMPLES.md` for usage guidance.
124+
113125
### DPoP Configuration Moved to Builder
114126

115127
The `useDPoP(context: Context)` method has been moved from the `WebAuthProvider` object to the login

auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt

Lines changed: 0 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import com.auth0.android.request.internal.GsonAdapter.Companion.forMapOf
2525
import com.auth0.android.request.internal.GsonProvider
2626
import com.auth0.android.request.internal.RequestFactory
2727
import com.auth0.android.request.internal.ResponseUtils.isNetworkError
28-
import com.auth0.android.result.Challenge
2928
import com.auth0.android.result.Credentials
3029
import com.auth0.android.result.DatabaseUser
3130
import com.auth0.android.result.PasskeyChallenge
@@ -175,42 +174,6 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
175174
}
176175

177176

178-
/**
179-
* Log in a user using the One Time Password code after they have received the 'mfa_required' error.
180-
* The MFA token tells the server the username or email, password, and realm values sent on the first request.
181-
*
182-
* Requires your client to have the **MFA OTP** Grant Type enabled. See [Client Grant Types](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it.
183-
*
184-
* Example usage:
185-
*
186-
*```
187-
* client.loginWithOTP("{mfa token}", "{one time password}")
188-
* .validateClaims() //mandatory
189-
* .start(object : Callback<Credentials, AuthenticationException> {
190-
* override fun onFailure(error: AuthenticationException) { }
191-
* override fun onSuccess(result: Credentials) { }
192-
* })
193-
*```
194-
*
195-
* @param mfaToken the token received in the previous [.login] response.
196-
* @param otp the one time password code provided by the resource owner, typically obtained from an
197-
* MFA application such as Google Authenticator or Guardian.
198-
* @return a request to configure and start that will yield [Credentials]
199-
*/
200-
@Deprecated(
201-
message = "loginWithOTP is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.",
202-
level = DeprecationLevel.WARNING
203-
)
204-
public fun loginWithOTP(mfaToken: String, otp: String): AuthenticationRequest {
205-
val parameters = ParameterBuilder.newBuilder()
206-
.setGrantType(ParameterBuilder.GRANT_TYPE_MFA_OTP)
207-
.set(MFA_TOKEN_KEY, mfaToken)
208-
.set(ONE_TIME_PASSWORD_KEY, otp)
209-
.asDictionary()
210-
return loginWithToken(parameters)
211-
}
212-
213-
214177
/**
215178
* Sign-in a user using passkeys.
216179
* This should be called after the client has received the passkey challenge from the server and generated the public key response.
@@ -391,132 +354,6 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
391354
.addParameters(parameters)
392355
}
393356

394-
/**
395-
* Log in a user using an Out Of Band authentication code after they have received the 'mfa_required' error.
396-
* The MFA token tells the server the username or email, password, and realm values sent on the first request.
397-
*
398-
* Requires your client to have the **MFA OOB** Grant Type enabled. See [Client Grant Types](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it.
399-
*
400-
* Example usage:
401-
*
402-
*```
403-
* client.loginWithOOB("{mfa token}", "{out of band code}", "{binding code}")
404-
* .validateClaims() //mandatory
405-
* .start(object : Callback<Credentials, AuthenticationException> {
406-
* override fun onFailure(error: AuthenticationException) { }
407-
* override fun onSuccess(result: Credentials) { }
408-
* })
409-
*```
410-
*
411-
* @param mfaToken the token received in the previous [.login] response.
412-
* @param oobCode the out of band code received in the challenge response.
413-
* @param bindingCode the code used to bind the side channel (used to deliver the challenge) with the main channel you are using to authenticate.
414-
* This is usually an OTP-like code delivered as part of the challenge message.
415-
* @return a request to configure and start that will yield [Credentials]
416-
*/
417-
@Deprecated(
418-
message = "loginWithOOB is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.",
419-
level = DeprecationLevel.WARNING
420-
)
421-
public fun loginWithOOB(
422-
mfaToken: String,
423-
oobCode: String,
424-
bindingCode: String? = null
425-
): AuthenticationRequest {
426-
val parameters = ParameterBuilder.newBuilder()
427-
.setGrantType(ParameterBuilder.GRANT_TYPE_MFA_OOB)
428-
.set(MFA_TOKEN_KEY, mfaToken)
429-
.set(OUT_OF_BAND_CODE_KEY, oobCode)
430-
.set(BINDING_CODE_KEY, bindingCode)
431-
.asDictionary()
432-
return loginWithToken(parameters)
433-
}
434-
435-
/**
436-
* Log in a user using a multi-factor authentication Recovery Code after they have received the 'mfa_required' error.
437-
* The MFA token tells the server the username or email, password, and realm values sent on the first request.
438-
*
439-
* Requires your client to have the **MFA** Grant Type enabled. See [Client Grant Types](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it.
440-
*
441-
* Example usage:
442-
*
443-
*```
444-
* client.loginWithRecoveryCode("{mfa token}", "{recovery code}")
445-
* .validateClaims() //mandatory
446-
* .start(object : Callback<Credentials, AuthenticationException> {
447-
* override fun onFailure(error: AuthenticationException) { }
448-
* override fun onSuccess(result: Credentials) { }
449-
* })
450-
*```
451-
*
452-
* @param mfaToken the token received in the previous [.login] response.
453-
* @param recoveryCode the recovery code provided by the end-user.
454-
* @return a request to configure and start that will yield [Credentials]. It might also include a [recoveryCode] field,
455-
* which your application must display to the end-user to be stored securely for future use.
456-
*/
457-
@Deprecated(
458-
message = "loginWithRecoveryCode is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.",
459-
level = DeprecationLevel.WARNING
460-
)
461-
public fun loginWithRecoveryCode(
462-
mfaToken: String,
463-
recoveryCode: String
464-
): AuthenticationRequest {
465-
val parameters = ParameterBuilder.newBuilder()
466-
.setGrantType(ParameterBuilder.GRANT_TYPE_MFA_RECOVERY_CODE)
467-
.set(MFA_TOKEN_KEY, mfaToken)
468-
.set(RECOVERY_CODE_KEY, recoveryCode)
469-
.asDictionary()
470-
return loginWithToken(parameters)
471-
}
472-
473-
/**
474-
* Request a challenge for multi-factor authentication (MFA) based on the challenge types supported by the application and user.
475-
* The challenge type is how the user will get the challenge and prove possession. Supported challenge types include: "otp" and "oob".
476-
*
477-
* Example usage:
478-
*
479-
*```
480-
* client.multifactorChallenge("{mfa token}", "{challenge type}", "{authenticator id}")
481-
* .start(object : Callback<Challenge, AuthenticationException> {
482-
* override fun onFailure(error: AuthenticationException) { }
483-
* override fun onSuccess(result: Challenge) { }
484-
* })
485-
*```
486-
*
487-
* @param mfaToken the token received in the previous [.login] response.
488-
* @param challengeType A whitespace-separated list of the challenges types accepted by your application.
489-
* Accepted challenge types are oob or otp. Excluding this parameter means that your client application
490-
* accepts all supported challenge types.
491-
* @param authenticatorId The ID of the authenticator to challenge.
492-
* @return a request to configure and start that will yield [Challenge]
493-
*/
494-
@Deprecated(
495-
message = "multifactorChallenge is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.",
496-
level = DeprecationLevel.WARNING
497-
)
498-
public fun multifactorChallenge(
499-
mfaToken: String,
500-
challengeType: String? = null,
501-
authenticatorId: String? = null
502-
): Request<Challenge, AuthenticationException> {
503-
val parameters = ParameterBuilder.newBuilder()
504-
.setClientId(clientId)
505-
.set(MFA_TOKEN_KEY, mfaToken)
506-
.set(CHALLENGE_TYPE_KEY, challengeType)
507-
.set(AUTHENTICATOR_ID_KEY, authenticatorId)
508-
.asDictionary()
509-
val url = auth0.getDomainUrl().toHttpUrl().newBuilder()
510-
.addPathSegment(MFA_PATH)
511-
.addPathSegment(CHALLENGE_PATH)
512-
.build()
513-
val challengeAdapter: JsonAdapter<Challenge> = GsonAdapter(
514-
Challenge::class.java, gson
515-
)
516-
return factory.post(url.toString(), challengeAdapter)
517-
.addParameters(parameters)
518-
}
519-
520357
/**
521358
* Log in a user using a token obtained from a Native Social Identity Provider, such as Facebook, using ['\oauth\token' endpoint](https://auth0.com/docs/api/authentication#token-exchange-for-native-social)
522359
* The default scope used is 'openid profile email'.
@@ -1128,13 +965,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
1128965
private const val OAUTH_CODE_KEY = "code"
1129966
private const val REDIRECT_URI_KEY = "redirect_uri"
1130967
private const val TOKEN_KEY = "token"
1131-
private const val MFA_TOKEN_KEY = "mfa_token"
1132968
private const val ONE_TIME_PASSWORD_KEY = "otp"
1133-
private const val OUT_OF_BAND_CODE_KEY = "oob_code"
1134-
private const val BINDING_CODE_KEY = "binding_code"
1135-
private const val CHALLENGE_TYPE_KEY = "challenge_type"
1136-
private const val AUTHENTICATOR_ID_KEY = "authenticator_id"
1137-
private const val RECOVERY_CODE_KEY = "recovery_code"
1138969
private const val SUBJECT_TOKEN_KEY = "subject_token"
1139970
private const val SUBJECT_TOKEN_TYPE_KEY = "subject_token_type"
1140971
private const val ORGANIZATION_KEY = "organization"
@@ -1151,7 +982,6 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
1151982
private const val TOKEN_PATH = "token"
1152983
private const val USER_INFO_PATH = "userinfo"
1153984
private const val REVOKE_PATH = "revoke"
1154-
private const val MFA_PATH = "mfa"
1155985
private const val CHALLENGE_PATH = "challenge"
1156986
private const val PASSKEY_PATH = "passkey"
1157987
private const val REGISTER_PATH = "register"

auth0/src/main/java/com/auth0/android/result/Challenge.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.google.gson.annotations.SerializedName
66
/**
77
* Multi-factor authentication (MFA) challenge
88
*
9-
* @see [com.auth0.android.authentication.AuthenticationAPIClient.multifactorChallenge]
9+
* @see [com.auth0.android.authentication.mfa.MfaApiClient]
1010
*/
1111
public class Challenge(
1212
@field:JsonRequired @field:SerializedName("challenge_type")

0 commit comments

Comments
 (0)