OpenID Connect (OIDC) is an identity layer built on top of the OAuth 2.0 protocol. It allows applications to verify the identity of a user and obtain basic profile information. This topic describes how to retrieve user information after a user authenticates with Alibaba Cloud using OIDC.
Prerequisites
You have created an OAuth 2.0 web application in the RAM console and securely stored its client secret. For more information, see Create an OAuth application, Manage OAuth scopes, and Create an application secret.
Your application has completed the OAuth 2.0 authorization code flow and obtained an ID token and an access token. For more information, see Access Alibaba Cloud APIs from a web application.
Overview of methods
After a user successfully authenticates and your application receives tokens, you can obtain the user's information in two ways:
Parse the ID token: The ID token is a JSON Web Token (JWT) that contains claims about the user's identity. You can validate and decode this token locally in your application to get user information without making another network request.
Call the UserInfo endpoint: You can use the access token to make an API call to the standard OIDC UserInfo endpoint, which returns a JSON object with the user's information.
Method 1: Parse the ID token
The ID token contains user information as claims. Before you can trust these claims, your application must validate the token.
Verify the token signature: The ID token is signed using the RS256 algorithm. You must verify its signature using the corresponding public key from the Alibaba Cloud JSON Web Key Set (JWKS).
The JWKS endpoint is available at:
https://oauth.alibabacloud.com/v1/keys.Your application should fetch the keys from this endpoint, find the key that matches the
kid(key ID) in the ID token's header, and use it to verify the signature.Do not cache the public keys for long periods, as they are rotated regularly.
Verify the claims: After verifying the signature, validate the following claims within the token's payload:
iss(Issuer): Must match the Alibaba Cloud OAuth issuer URL (https://oauth.alibabacloud.com).aud(Audience): Must match your application's ID.exp(Expiration time): Must be a time in the future.
Example: Verify an ID token signature in Java
The following example demonstrates how to fetch the public key and verify the signature of a signed JWT.
public class TokenVerifierSimple {
private static final Logger LOG = LoggerFactory.getLogger(TokenVerifierSimple.class);
public boolean verifySign(SignedJWT signedJWT) throws AuthenticationException {
HttpResponse response = HttpClientUtils.doGet("https://oauth.alibabacloud.com/v1/keys");
List<RSAKey> publicKeyList = new ArrayList<>();
if (response.getCode() == 200 && response.isSuccess()) {
String keys = JSON.parseObject(response.getData()).getString("keys");
try {
JSONArray publicKeyJsonArray = JSON.parseArray(keys);
for (Object object : publicKeyJsonArray) {
RSAKey rsaKey = RSAKey.parse(JSONObject.toJSONString(object));
publicKeyList.add(rsaKey);
}
} catch (Exception e) {
LOG.error("Failed to parse public keys", e);
throw new AuthenticationException("Failed to parse public keys from Alibaba Cloud.");
}
} else {
LOG.error("GetSignPublicKey failed: {}", response.getData());
throw new AuthenticationException("Failed to get public keys from Alibaba Cloud: " + response.getData());
}
RSAKey rsaKey = null;
String keyID = signedJWT.getHeader().getKeyID();
for (RSAKey key : publicKeyList) {
if (key.getKeyID().equals(keyID)) {
rsaKey = key;
break; // Exit the loop once the key is found
}
}
if (rsaKey != null) {
try {
RSASSAVerifier verifier = new RSASSAVerifier(rsaKey.toRSAPublicKey());
if (signedJWT.verify(verifier)) {
return true;
}
} catch (Exception e) {
LOG.error("Signature verification failed with exception", e);
// Even if an exception occurs, it should be treated as a verification failure and an AuthenticationException should be thrown.
throw new AuthenticationException("Signature verification failed due to an internal error.");
}
}
// If the key is not found or verification returns false
throw new AuthenticationException("Can't verify signature for id token. Invalid key or signature.");
}
}ID token claims
Once validated, you can extract the following claims from the ID token payload. The available claims depend on the OAuth scopes granted by the user.
Claim | Description | Required scope |
| A unique, non-PII identifier for the user. |
|
| The type of user. Valide values: |
|
| The display name of the RAM user or role. |
|
| The User Principal Name (UPN) of the RAM user. |
|
| The logon name of the Alibaba Cloud account. |
|
| The ID of the Alibaba Cloud account to which the user belongs. |
|
| The unique ID of the authenticated principal (Alibaba Cloud account ID, RAM user ID, or RAM role ID). |
|
Example ID token payloads
The following examples show the decoded payload for different user types.
Alibaba Cloud account:
{
"exp": 1517539523,
"sub": "123456789012****",
"aud": "4567890123456****",
"iss": "https://oauth.alibabacloud.com",
"iat": 1517535923,
"type": "account",
"login_name":"alice@example.com",
"aid": "123456789012****",
"uid": "123456789012****"
}RAM user:
{
"exp": 1517539523,
"sub": "123456789012****",
"aud": "4567890123456****",
"iss": "https://oauth.alibabacloud.com",
"iat": 1517535923,
"type": "user",
"name": "alice",
"upn": "alice@example.onaliyun.com",
"aid": "123456789012****",
"uid": "234567890123****"
}RAM role:
{
"exp": 1517539523,
"sub": "123456789012****",
"aud": "4567890123456****",
"iss": "https://oauth.aliyun.com",
"iat": 1517535923,
"type": "role",
"name": "NetworkAdministrator:alice",
"aid": "123456789012****",
"uid": "300800165472****"
}Method 2: Call the UserInfo endpoint
As an alternative to parsing the ID token, you can make an authenticated request to the UserInfo endpoint (https://oauth.alibabacloud.com/v1/userinfo) using the access token. This endpoint returns the user's information directly.
Example request
Make a GET request to the endpoint with the access token in the Authorization header.
GET v1/userinfo HTTP/1.1
Host: oauth.alibabacloud.com
Authorization: Bearer SIAV32hkKGExample response
The endpoint returns a JSON object containing the user's claims. The claims are the same as those available in the ID token.
Alibaba Cloud account:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "123456789012****",
"type": "account",
"login_name":"alice@example.com",
"aid": "123456789012****",
"uid": "123456789012****"
}RAM user:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "123456789012****",
"type": "user",
"name": "alice",
"upn": "alice@example.onaliyun.com",
"aid": "123456789012****",
"uid": "234567890123****"
}RAM role:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "123456789012****",
"type": "role",
"name": "NetworkAdministrator:alice",
"aid": "123456789012****",
"uid": "300800165472****"
}OIDC discovery endpoint
For automated client configuration, OIDC SPs expose a discovery endpoint that contains metadata about the provider's configuration, including the authorization, token, and JWKS endpoints. This is useful for client libraries that can auto-configure themselves.
Discovery endpoint: https://oauth.alibabacloud.com/.well-known/openid-configuration
Example content:
{
"code_challenge_methods_supported": [
"plain",
"S256"
],
"subject_types_supported": [
"public"
],
"response_types_supported": [
"code"
],
"issuer": "https://oauth.alibabacloud.com",
"jwks_uri": "https://oauth.alibabacloud.com/v1/keys",
"revocation_endpoint": "https://oauth.alibabacloud.com/v1/revoke",
"token_endpoint": "https://oauth.alibabacloud.com/v1/token",
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"aliuid",
"profile"
],
"authorization_endpoint": "https://signin.alibabacloud.com/oauth2/v1/auth"
}