Biometric (WebAuthn) integration
This topic describes how to integrate WebAuthn.
Prerequisites
Register an Alibaba Cloud account, complete identity verification, enable IDaaS, and create an application.
Obtain an Alibaba Cloud AccessKey pair.
Ensure that the WebAuthn authentication method is selected for your application. For more information, see Modify the authentication method of an application.
WebAuthn authenticator registration - initialization
This request initializes WebAuthn authenticator registration. It returns a parameter object that you can use to create WebAuthn credentials.
Request parameters
Name | Type | Required | Example | Description |
ApplicationExternalId | String | Yes | A0000001 | The external ID of the application. You specify this ID when you create the application. You can view it on the application's product page. |
AuthenticatorType | String | Yes | WEBAUTHN | The authentication method identity. When you call the WebAuthn authentication API, this is a static field: WEBAUTHN. |
UserId | String | Yes | user-test-1 | The unique identifier of the user, such as a user ID, mobile number, or email address. |
Username | String | No | Zhang San | The username. |
UserDisplayName | String | No | Xiao Zhang | The user's nickname. |
ServerExtendParamsJson | String | No | eyJhdHRhY2htZW50IjoicGxhdGZvcm0iLCJ1c2VyVmVyaWZpY2F0aW9uIjoicmVxdWlyZWQifQ== | The WebAuthn registration context. This is a JSON string. |
ServerExtendParamsJson parameter parsing
Name | Type | Required | Example value | Description |
attachment | String | No | platform | The default value is |
userVerification | String | No | required | The default value is |
Response data
Name | Type | Example | Description |
Success | boolean | true | The result of the operation. `true` indicates success. `false` indicates failure. |
Code | String | Opreation.Success | The status code. If `Success` is `true`, the value of `Code` is `Operation.Success`. If `Success` is `false`, see the error codes below for the value of `Code`. |
Message | String | Opreation.Success | The description. If `Success` is `false`, this provides a detailed description of the error code. |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | {"challengeBase64":"AAAAAXzBzvy0MTIzMjMxMjMxMg==","requestId":"2D503C0A-57FB-556E-B7BD-5E117EFA1541","options":"{\"attestation\":\"none\",\"authenticatorSelection\":{\"userVerification\":\"required\"},\"challengeBase64\":\"AAAAAXzBzvy0MTIzMjMxMjMxMg==\",\"excludeCredentials\":[],\"pubKeyCredParams\":[{\"alg\":-7,\"type\":\"public-key\"},{\"alg\":-257,\"type\":\"public-key\"}],\"rp\":{\"id\":\"localhost\",\"name\":\"Test\"},\"timeout\":60000,\"user\":{\"displayName\":\"1232312312\",\"id\":\"1232312312\",\"name\":\"1232312312\"}}"} | If the operation is successful, the `Data` JSON string contains two fields:
If the operation fails, the `Data` field is empty. |
Request example
Request method: POST
https://idaas-doraemon.aliyuncs.com/?
Action=CreateAuthenticatorRegistration
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=WEBAUTHN
&UserId=user-test-1
&UserName=user-test-1
&UserDisplayName=user-test-1
&ServerExtendParamsJson=eyJhcHBJ...biI6IjEuMCJ9
&<Common request parameters>Example of a successful response for WebAuthn authenticator registration initialization:
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-****-****-1B9BC80E58B6",
"Data": {
"challengeBase64": "AAAAAXzAn9aPMTIzMjMxMjMxMg==",
"requestId": "91DBDD36-B05C-5AF1-B205-E1708EC5B792",
"options": "{\"attestation\":\"none\",\"authenticatorSelection\":{\"userVerification\":\"required\"},\"challengeBase64\":\"AAAAAXzAn9aPMTIzMjMxMjMxMg==\",\"excludeCredentials\":[],\"pubKeyCredParams\":[{\"alg\":-7,\"type\":\"public-key\"},{\"alg\":-257,\"type\":\"public-key\"}],\"rp\":{\"id\":\"localhost\",\"name\":\"Test (Do not delete)\"},\"timeout\":60000,\"user\":{\"displayName\":\"1232312312\",\"id\":\"1232312312\",\"name\":\"1232312312\"}}"
}
}Example of an error response when the authentication method identity is missing from the request parameters:
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data": null
}WebAuthn authenticator registration - verification
This request verifies and registers a WebAuthn authenticator. The main tasks are to verify the request and attach the authenticator to the user ID.
Scenarios: Registration, enabling WebAuthn for passwordless logon, and two-factor authentication.
Request parameters
Name | Type | Required | Example | Description |
ApplicationExternalId | String | Yes | A0000001 | The external ID of the application. You specify this ID when you create the application. You can view it on the application's product page. |
AuthenticatorType | String | Yes | WEBAUTHN | The authentication method identity. When you call the WebAuthn authentication API, this is a static field: WEBAUTHN. |
UserId | String | Yes | user-test-1 | The unique identifier of the user, such as a user ID, mobile number, or email address. |
AuthenticatorName | String | No | webAuthn authenticator | The authenticator name. |
RequireChallengeBase64 | String | No | AAAAAXzAn9aPMTIzMjMxMjMxMg== | The `ChallengeBase64` returned by the authenticator creation initialization request. |
ServerExtendParamsJson | String | No | eyJhdHRhY2htZW50IjoicGxhdGZvcm0iLCJ1c2VyVmVyaWZpY2F0aW9uIjoicmVxdWlyZWQifQ== | The WebAuthn registration context. This is a JSON string. |
RegistrationContext | String | Yes | The registration information generated by the JavaScript SDK. This is a JSON string. For details about the parameters, see the RegistrationContext parameter parsing section below. | |
UserSourceIp | String | No | 127.0.0.1 | The client IP address. |
RegistrationContext parameter parsing:
For webauthn, RegistrationContext is a JSON object that contains the following information:
Field | Type | Notes |
credentialId | String | The credential ID, which is URI-ENCODED-BASE64(RAW_ID). This information uniquely identifies a WebAuthn authenticator. |
type | String | The value is fixed at |
transports | String | This method is part of the WebAuthn interface. |
attestationObjectBase64 | String | The registered attestation object. |
clientDataJSONBase64 | String | The client data JSON. |
ServerExtendParamsJson parameter parsing:
For WebAuthn, `ServerExtendParamsJson` can be empty to use the default value, or it can be configured with the following parameters:
Field | Type | Required | Notes |
requireUserPresence | Boolean | No | The default value is |
requireUserVerification | Boolean | No | The default value is |
Returned count
Name | Type | Example | Description |
Success | boolean | true | The result of the operation. `true` indicates success. `false` indicates failure. |
Code | String | Opreation.Success | The status code. If `Success` is `true`, the value of `Code` is `Operation.Success`. If `Success` is `false`, see the error codes below for the value of `Code`. |
Message | String | Opreation.Success | The description. If `Success` is `false`, this provides a detailed description of the error code. |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | {"authenticatorUuid": "1C0EE50AB3BB42FDAB59E3FE88976982"} | If the operation is successful, the `Data` JSON string contains one field:
If the operation fails, the `Data` field is empty. |
Sample request
Request method: POST
https://idaas-doraemon.aliyuncs.com/?
Action=RegisterAuthenticator
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=WEBAUTHN
&UserId=user-test-1
&AuthenticatorName=user-test-1
&RequireChallengeBase64="MGVhMGViYzYzNjc4YWZlYzMx********YTlhNzViMjFHdU5kMjIySjZtYw=="
&ServerExtendParamsJson=eyJhcHBJ***biI6IjEuMCJ9
&RegistrationContext="xxxx"
&UserSourceIp=1.1.*.*
&<Common request parameters>Example of a successful response for verifying a WebAuthn authenticator registration:
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-****-****-1B9BC80E58B6",
"Data": {
"authenticatorUuid": "1C0EE50AB3BB********E3FE88976982"
}
}Example of an error response when the authentication method identity is missing from the request parameters:
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data":null
}WebAuthn authenticator authentication - initialization
This request initializes WebAuthn authenticator authentication.
Request parameters
Name | Type | Required | Example value | Description |
ApplicationExternalId | String | Yes | A0000001 | The external ID of the application. You specify this ID when you create the application. You can view it on the application's product page. |
AuthenticatorType | String | Yes | WEBAUTHN | The authentication method identity. When you call the WebAuthn authentication API, this is a static field: WEBAUTHN. |
UserId | String | Yes | user-test-1 | The unique identifier of the user, such as a user ID, mobile number, or email address. |
BindHashBase64 | String | No | Used to generate a challenge and attach it to the `BindHash` parameter. In a specific business scenario, this can be attached to the hash of a user transaction. This means a WebAuthn authentication can be attached to a specific user business operation. |
Response data
Name | Type | Example | Description |
Success | boolean | true | The result of the operation. `true` indicates success. `false` indicates failure. |
Code | String | Opreation.Success | The status code. If `Success` is `true`, the value of `Code` is `Operation.Success`. If `Success` is `false`, see the error codes below for the value of `Code`. |
Message | String | Opreation.Success | The description. If `Success` is `false`, this provides a detailed description of the error code. |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | "challengeBase64": "AQAAAXydKjV+NlhrSlpPMHAxeHZPWlFJQTBiNXlRWU5s", "options": "{\"allowCredentials\":[{\"idBase64\":\"Z0MkHYJnRDbGfa0LvWvvO6UqcNjFwCIR6mpNTl8jfTA\",\"transports\":[],\"type\":\"public-key\"}],\"challengeBase64\":\"AQAAAXydKjV+NlhrSlpPMHAxeHZPWlFJQTBiNXlRWU5s\",\"rpId\":\"localhost\",\"timeout\":60000,\"userVerification\":\"preferred\"}" } | If the operation is successful, the `Data` JSON string contains two fields:
If the operation fails, the `Data` field is empty. |
Request example
Request method: POST
https://idaas-doraemon.aliyuncs.com/?
Action=CreateUserAuthenticateOptions
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=WEBAUTHN
&UserId=user-test-1
&BindHashBase64=******
&<Common request parameters>Example of a successful response for WebAuthn authenticator authentication initialization:
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-****-****-1B9BC80E58B6",
"Data": {
"challengeBase64": "AQAAAXydKjV+NlhrSlpPMHAxeHZPWlFJQTBiNXlRWU5s",
"options": "{\"allowCredentials\":[{\"idBase64\":\"Z0MkHYJnRDbGfa0LvWvvO6UqcNjFwCIR6mpNTl8jfTA\",\"transports\":[],\"type\":\"public-key\"}],\"challengeBase64\":\"AQAAAXydKjV+NlhrSlpPMHAxeHZPWlFJQTBiNXlRWU5s\",\"rpId\":\"localhost\",\"timeout\":60000,\"userVerification\":\"preferred\"}"
}
}Example of an error response when the authentication method identity is missing from the request parameters:
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data": null
}WebAuthn authenticator authentication
This request authenticates a user with a WebAuthn authenticator.
Name | Type | Required | Example | Description |
ApplicationExternalId | String | Yes | A0000001 | The external ID of the application. You specify this ID when you create the application. You can view it on the application's product page. |
AuthenticatorType | String | Yes | WEBAUTHN | The authenticator type. This is a static field: WEBAUTHN |
AuthenticationContext | String | Yes | Information generated by the JavaScript SDK. | |
UserId | String | Yes | user-test-1 | The user ID. |
ServerExtendParamsJson | String | No | Used to configure user presence (UP), user verification (UV), and `SignCount` increment. | |
RequireChallengeBase64 | String | No | If not provided, no check is performed. Only the challenge's validity period and anti-replay are checked. | |
RequireBindHashBase64 | String | No | For its function, see the `BindHashBase64` parameter in the "WebAuthn authenticator authentication - initialization" section. | |
UserSourceIp | String | No | 127.0.0.1 | The user's IP address. This is recorded in the audit log. |
AuthenticationContext parameter parsing:
For webauthn, AuthenticationContext is a JSON object that contains the following information:
Field | Type | Notes |
userAgent | String | The application proxy. |
credentialId | String | The credential ID. |
type | String | Currently, this is a static field: |
authenticatorDataBase64 | String | The authenticator data JSON. |
clientDataJSONBase64 | String | The client data JSON. |
signatureBase64 | String | The signature. |
userHandleBase64 | String | The user handle (which is the user ID). |
ServerExtendParamsJson parameter parsing:
For WebAuthn, `ServerExtendParamsJson` can be empty to use the default value, or it can be configured with the following parameters:
Field | Type | Required | Notes |
requireUserPresence | Boolean | No | The default value is consistent with the authenticator's UP value. Specifies whether user presence is required. |
requireUserVerification | Boolean | No | The default value is consistent with the authenticator's UV value. Specifies whether user verification is required. |
requireSignCountIncrement | Boolean | No | The default value is |
Name | Type | Example | Description |
Success | boolean | true | The result of the operation. `true` indicates success. `false` indicates failure. |
Code | String | Opreation.Success | The status code.
|
Message | String | Opreation.Success | The description. If `Success` is `false`, this provides a detailed description of the error code. |
RequestId | String | 1C0EE50A-B3BB-42FD-AB59-E3FE88976982 | The request ID. |
Data | String | { "verifyResult": true, "authenticateResultInfo": { "credentialId": "Z0MkHYJnRDbGfa0LvWvvO6UqcNjFwCIR6mpNTl8jfTA", "bindHashBase64": null, "userId": "abcdefg" } | If the operation is successful, the `Data` JSON string contains five fields:
If the operation fails, the `Data` field is empty. |
Request method: POST
https://idaas-doraemon.aliyuncs.com/?
Action=VerifyUserAuthentication
&Version=2021-05-20
&ApplicationExternalId=A0000001
&AuthenticatorType=WEBAUTHN
&UserId=user-test-1
&AuthenticationContext=xxxxx
&ServerExtendParamsJson=eyJwaG9uZU51bWJlciI6IjAwMDAwMDAwMDAwIn0=
&UserSourceIp=1.1.*.*
&<Common request parameters>Example of a successful response for a WebAuthn authenticator authentication request:
{
"Success": true,
"Code": "Operation.Success",
"Message": "Operation.Success",
"RequestId": "337848D2-FF8A-****-****-1B9BC80E58B6",
"Data": {
"verifyResult": true,
"authenticateResultInfo": {
"credentialId": "Z0MkHYJnRDbGfa0LvWvvO6UqcNjFwCIR6mpNTl8jfTA",
"bindHashBase64": null,
"userId": "abcdefg"
}
}
}Example of an error response when the authentication method identity is missing from the request parameters:
{
"Success": false,
"Code": "Params.Blank",
"Message": "Params.Blank.APIInvokeParams.AuthenticatorType",
"RequestId": "1C0EE50A-B3BB-42FD-AB59-E3FE88976982",
"Data":null
}Code example (Java)
The following code provides an example of WebAuthn authentication:
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 {
/**
* Use an AccessKey pair to initialize the client.
*
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
public static IAcsClient createClient(String accessKeyId, String accessKeySecret) throws Exception {
// An Alibaba Cloud account's AccessKey pair has full permissions for all APIs, which poses a high security risk. We highly recommend that you create and use a Resource Access Management (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 highly recommend that you do not hard-code the AccessKey pair into 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 WebAuthn authenticator registration.
registerWebAuthnInit();
// Register the WebAuthn authenticator.
registerWebAuthnVerify();
// Initialize WebAuthn authentication.
webAuthnVerifyInit();
// Perform WebAuthn verification.
}
public void registerWebAuthnInit() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
// Initialize WebAuthn authenticator registration.
CreateAuthenticatorRegistrationRequest request = new CreateAuthenticatorRegistrationRequest();
request.setApplicationExternalId("testApplication");
request.setAuthenticatorType("WEBAUTHN");
request.setUserId("1232312312");
request.setUserName("1232312312");
request.setUserDisplayName("1232312312");
request.setServerExtendParamsJson("eyJhdHRhY2htZW50IjoicGxhdGZvcm0iLCJ1c2VyVmVyaWZpY2F0aW9uIjoicmVxdWlyZWQifQ==");
// If you copy this code to run, print the API return value yourself.
try {
CreateAuthenticatorRegistrationResponse response = client.getAcsResponse(request);
System.out.println(response.getChallengeBase64());
} catch (Exception e) {
// Determine the cause of the exception based on e.getCode().
System.out.println(e);
}
}
public void registerWebAuthnVerify() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
// Register WebAuthn authenticator - verification.
RegisterAuthenticatorRequest request = new RegisterAuthenticatorRequest();
request.setApplicationExternalId("testApplication");
request.setAuthenticatorType("WEBAUTHN");
request.setUserId("1232312312");
request.setAuthenticatorName("Authenticator");
request.setRequireChallengeBase64("AAAAAXy71/wtMTIzMjMxMjMxMg==");
request.setRegistrationContext("{\"base64Challenge\":\"AAAAAXy71/wtMTIzMjMxMjMxMg==\",\"otpCode\":\"304288\"}");
request.setUserSourceIp("47.100.XX.XX");
// If you copy this code to run, print the API return value yourself.
try {
RegisterAuthenticatorResponse response = client.getAcsResponse(request);
System.out.println(response.getAuthenticatorUuid());
} catch (Exception e) {
// Determine the cause of the exception based on e.getCode().
System.out.println(e);
}
}
public void webAuthnVerifyInit() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
// WebAuthn authenticator - verification initialization.
CreateUserAuthenticateOptionsRequest request = new CreateUserAuthenticateOptionsRequest();
request.setApplicationExternalId("testApplication");
request.setAuthenticatorType("WEBAUTHN");
request.setUserId("1232312312");
// If you copy this code to run, print the API return value yourself.
try {
CreateUserAuthenticateOptionsResponse response = client.getAcsResponse(request);
System.out.println(response.getOptions());
} catch (Exception e) {
// Determine the cause of the exception based on e.getCode().
System.out.println(e);
}
}
public void webAuthnVerify() throws Exception {
IAcsClient client = IDaaSAuthSample.createClient("Your AccessKey", "Your AccessSecret");
// WebAuthn authenticator - verification.
VerifyUserAuthenticationRequest request = new VerifyUserAuthenticationRequest();
request.setApplicationExternalId("testApplication");
request.setAuthenticatorType("WEBAUTHN");
request.setUserId("1232312312");
request.setAuthenticationContext("");
// If you copy this code to run, print the API return value yourself.
try {
VerifyUserAuthenticationResponse response = client.getAcsResponse(request);
System.out.println(response.getAuthenticateResultInfo());
} catch (Exception e) {
// Determine the cause of the exception based on e.getCode().
System.out.println(e);
}
}
}The sample code requires the following Maven dependencies:
<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>
<version>[4.4.9,5.0.0)</version>
<optional>true</optional>
</dependency>