Use a TOTP authenticator
This topic describes how to use a time-based one-time password (TOTP) authenticator.
Before you begin
Create an Alibaba Cloud account, complete real-name verification, create a Secure Authentication instance, and then create an application for the instance.
Make sure that you select TOTP as the authentication method for your application. For more information, see Change the authentication method for an application.
CreateAuthenticatorRegistration
Initializes TOTP authenticator registration. This operation returns a parameter object that is required to register a TOTP authenticator.
Request parameters
Name | Type | Required | Example | Description |
ApplicationExternalId | String | Yes | A0000001 | The application ID. The ID is specified when you create the application. You can view the ID in the details panel of the application. |
AuthenticatorType | String | Yes | TOTP | The authentication method. Set the value to TOTP. |
UserId | String | Yes | user-test-1 | The unique identifier of the user, such as the user ID, mobile number, or email address. |
Username | String | No | Zhang San | The username. |
UserDisplayName | String | No | Zhang | The nickname of the user. |
RegistrationContext | String | No | {\"algorithm\":\"HmacSHA1\",\"period\":30,\"keySeedRespMode\":\"GOOGLE_QR\",\"issuer\":\"GItHub\"} | The JSON string that contains information about how to register a TOTP authenticator. |
Parsing the RegistrationContext parameter
Name | Type | Required | Sample value | Description |
algorithm | String | No | HmacSHA1 | The algorithm that generates the token. Valid values: HmacSHA1 HmacSHA256 HmacSHA512 SM3 |
period | int | No | 30 | The validity period of the token. Unit: seconds. Valid values: 30 and 60. Default value: 30. |
keySeedRespMode | String | Yes | GOOGLE_QR | The key return pattern identifier is a static field that specifies how key information is returned. GOOGLE_QR: QR code RAW_HEX: hexadecimal string RAW_BASE64: Base64-encoded string RAW_BASE32: Base32-encoded string |
issuer | String | Yes | For Issuer, enter the name of the current system. | |
qrCodeImgWidth | int | No | 200 | The width of the QR code image. The value of this parameter is valid only if you set keySeedRespMode to GOOGLE_QR. |
qrCodeImgHeight | int | No | 200 | The height of the QR code image. The value of this parameter is valid only if you set keySeedRespMode to GOOGLE_QR. |
Returned Data
Name | Type | Example value | Description |
Success | boolean | true | Indicates whether the request was successful. A value of true indicates that the request was successful. A value of false indicates that the request failed. |
Code | String | Opreation.Success | The response code. If the request was successful, Operation.Success is returned. If the request failed, an error code is returned. |
Message | String | Opreation.Success | The detailed description. This parameter is returned when `Success` is `false` and provides details about the `Code`. |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | { "challengeBase64": "MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw==", "options": "{\"algorithm\":\"HmacSHA1\",\"encodedSeed\":\"xxxxxx\",\"period\":30,\"seedEncodedFormat\":\"GOOGLE_QR\",\"user\":{\"displayName\":\"\",\"id\":\"2ue3bxdsbaofhns7x290bkn0u83whndincma\",\"name\":\"\"}}" } | When the operation succeeds, the Data field contains a JSON string with two fields:
If the operation fails, the Data field is empty. |
Examples
Request method: POST
https://idaas-doraemon.aliyuncs.com/?Action=CreateAuthenticatorRegistration
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=TOTP
&UserId=user-test-1
&UserName=user-test-1
&UserDisplayName=user-test-1
&RegistrationContext=eyJhcHBJ...biI6IjEuMCJ9
&<Common request parameters>Sample success response
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-4EDD-BD4D-1B9BC80E58B6",
"Data": {
"challengeBase64": "MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw==",
"options": "{\"algorithm\":\"HmacSHA1\",\"encodedSeed\":\"xxxxxx\",\"period\":30,\"seedEncodedFormat\":\"GOOGLE_QR\",\"user\":{\"displayName\":\"\",\"id\":\"2ue3bxdsbaofhns7x290bkn0u83whndincma\",\"name\":\"\"}}"
}
}Sample error response for a missing authentication method identity in request parameters
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data":null
}TOTP Authenticator Registration and Authentication
Registers a TOTP authenticator. This operation verifies the validity of the authenticator and binds a user ID to the authenticator.
Scenarios:
A user has logged on to a PC client and enables TOTP authentication.
Request parameters
Name | Type | Required | Example | Description |
ApplicationExternalId | String | Yes | A0000001 | The application ID. The ID is specified when you create the application. You can view the ID in the details panel of the application. |
AuthenticatorType | String | Yes | TOTP | The authentication method. Set the value to TOTP. |
UserId | String | Yes | user-test-1 | The unique identifier of the user, such as the user ID, mobile number, or email address. |
AuthenticatorName | String | No | Google Authenticator | The name of the authenticator. |
RequireChallengeBase64 | String | No | MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw== | The anti-replay challenge code that is returned when you request to initialize the authenticator registration. |
RegistrationContext | String | No | {\"base64Challenge\":\"MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw==\",\"otpCode\":\"123456\"} | The JSON string that contains the information about how to verify the TOTP authenticator registration. For more information, see the "RegistrationContext" section of this topic. |
UserSourceIp | String | No |
Parsing the RegistrationContext parameter
Name | Type | Required | Example | Description |
base64Challenge | String | Yes | MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw== | The anti-replay challenge code. |
otpCode | String | Yes | 123456 | The dynamic password. |
Return value
Name | Type | Example value | Description |
Success | boolean | true | Indicates whether the request was successful. A value of true indicates that the request was successful. A value of false indicates that the request failed. |
Code | String | Opreation.Success | The response code. If the request was successful, Operation.Success is returned. If the request failed, an error code is returned. |
Message | String | Opreation.Success | If `Success` is `false`, a detailed description of the `Code` is returned. |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | { "authenticatorUuid": "138dc94bcd6fb9ed2189474c97444c337kURpzUyQp1" } | If the operation is successful, the Data field contains a JSON string with one field:
If the operation fails, the Data field is empty. |
Examples
Request method: POST
https://idaas-doraemon.aliyuncs.com/?Action=RegisterAuthenticator
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=TOTP
&UserId=user-test-1
&AuthenticatorName=user-test-1
&RequireChallengeBase64="MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw=="
&RegistrationContext="{\"base64Challenge\":\"MGVhMGViYzYzNjc4YWZlYzMxYmIzODUxYTlhNzViMjFHdU5kMjIySjZtYw==\",\"otpCode\":\"123456\"}"
&UserSourceIp=1.1.X.X
&<Common request parameters>Sample response for a successful TOTP authenticator registration
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-4EDD-BD4D-1B9BC80E58B6",
"Data": {
"authenticatorUuid": "1C0EE50AB3BB42FDAB59E3FE88976982"
}
}Example of an error response: The authentication method identifier is missing from the request parameters.
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data":null
}TOTP authenticator - Authentication
Requests TOTP authentication for logon or sensitive operations.
Request parameters
Name | Type | Required | Example | Description |
ApplicationExternalId | String | Yes | A0000001 | The application ID. The ID is specified when you create the application. You can view the ID in the details panel of the application. |
ServiceCode | String | Yes | TOTP | The authentication method. Set the value to TOTP. |
DoraemonAction | String | Yes | VerifyOTP | The type of the operation. Set the value to VerifyOTP. |
ServerExtendParamsJson | String | Yes | eyJ1bmlxdWVJZCI6IjEyMzIzMTIzMTIiLCJ1bmlxdWVJZFR5cGUiOiJVU0VSX0lEIiwiY29kZSI6IjExMDIwNSIsInZlcmlmeU1vZGUiOiJQTEFJTiJ9 | The value for ServerExtendParamsJson must be a Base64-encoded JSON string. |
XClientIp | String | No | 127.0.0.1 | The IP address of the client. |
Parsing the ServerExtendParamsJson parameter
Name | Type | Required | Example | Description |
uniqueId | String | Yes | userid-test-1 | Required. The unique identifier of the authenticator or the unique ID of the user. Each value of uniqueIdType has a different meaning. |
code | String | Yes | 123456 | The dynamic password. |
uniqueIdType | String | No | USER_ID | Optional. Specifies the meaning of `uniqueId`. The valid values are:
If you do not specify this parameter, the default value OTP_UID is used. |
verifyMode | String | No | PLAN | The verification mode. Valid values:
If you do not specify this parameter, the default value PLAIN is used. |
Base64EncodedChapChallenge | String | No | This parameter is required if you set verifyMode to CHAP. | |
Base64EncodedMsChapV2ServerChallenge | String | No | This parameter is required if you set verifyMode to MS-CHAP-V2. | |
Base64EncodedMsChapV2ClientChallenge | String | No | Base64EncodedMsChapV2ClientChallenge |
Returned data
Name | Type | Example | Description |
Success | boolean | true | Indicates whether the request was successful. A value of true indicates that the request was successful. A value of false indicates that the request failed. |
Code | String | Opreation.Success | The response code. If the request was successful, Operation.Success is returned. If the request failed, an error code is returned. |
Message | String | Opreation.Success | The |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | "{\"state\":\"7d36722302b6b323ba28fc064e91d56aq88S6Zih4Bq\"}" | If the operation is successful, the JSON string in the Data field contains the following field:
The Data field is empty if the operation fails. |
Request example
Request method: POST
https://idaas-doraemon.aliyuncs.com/?Action=ServiceInvoke
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=TOTP
&UserId=user-test-1
&Action=VerifyOTP
&ServerExtendParamsJson=eyJwaG9uZU51bWJlciI6IjAwMDAwMDAwMDAwIn0=
&UserSourceIp=1.1.X.XSuccessful response for TOTP authenticator registration
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-4EDD-BD4D-1B9BC80E58B6",
"Data":"{\"state\":\"7d36722302b6b323ba28fc064e91d56aq88S6Zih4Bq\"}"
}Example error response: Missing authentication method identity parameter
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data":null
}Sample code in Java
To import the server-side SDK package into a Java Maven project, add the following coordinates.
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-idaas-doraemon</artifactId>
<version>1.2.4</version>
</dependency>The following sample code provides an example on how to use a TOTP authenticator:
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.idaas_doraemon.model.v20210520.*;
import com.aliyuncs.profile.DefaultProfile;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class IDaaSAuthSample {
/**
* Initializes the client using an AccessKey pair.
*
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
public static IAcsClient createClient(String accessKeyId, String accessKeySecret) throws Exception {
// An Alibaba Cloud account AccessKey has full permissions on all APIs, which poses a high security risk. We strongly recommend that you create and use a RAM user for API access or daily O&M. Log on to the RAM console to create a RAM user.
// This example shows how to store the AccessKey pair in environment variables. You can also store them in a configuration file as needed.
// We strongly recommend that you do not hard-code the AccessKey pair in your code. This can lead to security risks.
String accessKeyId = System.getenv("ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ACCESS_KEY_SECRET");
DefaultProfile profile = DefaultProfile.getProfile(
"cn-hangzhou",
accessKeyId,
accessKeySecret);
// addEndpoint
DefaultProfile.addEndpoint("cn-hangzhou",
"idaas-doraemon",
"idaas-doraemon.aliyuncs.com");
// The endpoint to access.
return new DefaultAcsClient(profile);
}
public static void main(String[] args_) throws Exception {
// Initialize TOTP authenticator registration.
registerInit();
// Register the TOTP authenticator.
registerVerify();
// Perform TOTP authentication.
totpVerify();
}
public void registerInit() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
//Initialize TOTP authenticator registration.
CreateAuthenticatorRegistrationRequest request = new CreateAuthenticatorRegistrationRequest();
request.setApplicationExternalId("testApplication");
request.setAuthenticatorType("TOTP");
request.setUserId("1232312312");
request.setUserName("1232312312");
request.setUserDisplayName("1232312312");
request.setRegistrationContext("{\"algorithm\":\"HmacSHA1\",\"keySeedRespMode\":\"GOOGLE_QR\",\"qrCodeImgWidth\":200,\"qrCodeImgHeight\":200,\"issuer\":\"AliIDaaSSecurityAuth\"}");
// Print the API response to view the result.
try {
CreateAuthenticatorRegistrationResponse response = client.getAcsResponse(request);
System.out.println(response.getChallengeBase64());
} catch (Exception e) {
//Determine the cause of the exception from e.getCode().
System.out.println(e);
}
}
public void registerVerify() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
//Verify TOTP authenticator registration.
RegisterAuthenticatorRequest request = new RegisterAuthenticatorRequest();
request.setApplicationExternalId("testApplication");
request.setAuthenticatorType("TOTP");
request.setUserId("1232312312");
request.setAuthenticatorName("Test Authenticator");
request.setRequireChallengeBase64("MjY1M2I3OTA1NWEwMDY2YmYxN2Y1YjA3NDdkZTM5NjdOSHVIU3c2czhPaQ==");
request.setRegistrationContext("{\"base64Challenge\":\"MjY1M2I3OTA1NWEwMDY2YmYxN2Y1YjA3NDdkZTM5NjdOSHVIU3c2czhPaQ==\",\"otpCode\":\"304288\"}");
request.setUserSourceIp("47.100.XX.XX");
// Print the API response to view the result.
try {
RegisterAuthenticatorResponse response = client.getAcsResponse(request);
System.out.println(response.getAuthenticatorUuid());
} catch (Exception e) {
//Determine the cause of the exception from e.getCode().
System.out.println(e);
}
}
public void totpVerify() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
//Verify with the TOTP authenticator.
ServiceInvokeRequest request = new ServiceInvokeRequest();
request.setApplicationExternalId("testApplication");
request.setServiceCode("TOTP");
request.setDoraemonAction("VerifyOTP");
request.setServerExtendParamsJson("eyJ1bmlxdWVJZCI6InVzZXJpZC10ZXN0LTEiLCJjb2RlIjoiMTIzNDU2IiwidW5pcXVlSWRUeXBlIjoiVVNFUl9JRCIsInZlcmlmeU1vZGUiOiJQTEFJTiJ9");
// Print the API response to view the result.
try {
ServiceInvokeResponse response = client.getAcsResponse(request);
System.out.println(response.getData());
} catch (Exception e) {
//Determine the cause of the exception from e.getCode().
System.out.println(e);
}
}
}Maven dependencies of the sample code
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-idaas-doraemon</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<optional>true</optional>
<version>[4.4.9,5.0.0)</version>
</dependency>