All Products
Search
Document Center

Identity as a Service:Integrate SSO by OIDC

Last Updated:Aug 05, 2024

1. Background

IDaaS uses the authorization code mechanism based on the standard Open ID Connect (OIDC) protocol to implement SSO for custom applications of enterprises.

SSO is implemented in the same way as logon by scanning QR codes with WeChat. Social identity providers (IdPs) such as DingTalk and WeChat use the OAuth protocol to implement QR code-based logon. The OIDC protocol used by IDaaS is an upgraded version of the Open Authorization (OAuth) protocol.

Note

Compatibility with OAuth: The OIDC 1.0 protocol creates a user identity layer on top of the OAuth2.0 protocol. Therefore, the OIDC protocol is compatible with the OAuth2.0 protocol. The OIDC authorization code flow is similar to the OAuth2.0 authorization code flow. The difference is that when OIDC authorization code flow is used, the user information endpoint is standardized, and the id-token of a user is returned from the token endpoint.

How the authorization code flow works

For custom applications, SSO is implemented by using the OIDC authorization code flow.

Your application only needs to interact with IDaaS at the authorization endpoint and token endpoint to complete the main process of SSO.

The logon process is fully hosted by IDaaS. Your application only needs to parse the logon result.

2. Implement SSO

2.1. Create a custom application or an OIDC-based application

You must create a custom application or an OIDC-based application in IDaaS and obtain the application keys. If you have obtained the application keys, skip this step.

For more information about how to create an application, see 3. Custom applications.

You can obtain client_id and client_secret by performing the following steps: Click Applications in the left-side navigation pane, click the application you want to manage on the Applications page, and then click the General tab to view the information. This key pair is used in the subsequent API requests.

image

For more information about how to manage or replace the key pair, see General settings.

2.2. Send a request to the authorization endpoint

The following steps are performed by the application developer.

When a user attempts to access your application, the application must check whether a logged-on identity of the user is available.

If the user needs to log on to your application, you must send a request to IDaaS for the authorization of the user to access their information. You can click Applications in the left-side navigation pane, click the application you want to manage on the Applications page, click the Sign-In tab, and then view the authorization endpoint of the application in Application Settings.

image

In addition, you must generate a complete authorization request URL based on the authorization endpoint and initiate a 302 redirect in the browser. The following code provides an example.

{{Authorization Endpoint}}?
  client_id=app_***&
  redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F***&
  response_type=code&
  scope=openid&
  state=525f49cc-***

Parameter

Required

Example

Description

client_id

Yes

app_michs7r****6pye

The client_id obtained in the previous step.

scope

Yes

openid email profile

By default, the value is set to openid email profile for a custom application. This indicates that the application can obtain the ID, username, and email address of the logged-on account. If you use an OIDC-based application, the administrator can also select Phone on the configuration page. For more information about the parameter values the application is authorized to obtain when scope is specified, see 3.2 Mapping between the parameter values accessible to applications and specified scope in this topic.

response_type

Yes

code

The value of this parameter is fixed as code. The value indicates that the authorization code mode is used.

redirect_uri

Yes

http://localhost:3000/user/oauth2/aliyunidaas/callback

The redirect URL of the logon result that is returned by IDaaS to the application after the user logs on to the application. This URL is a relay address for the application to receive IDaaS parameters and can receive the authorization code.

state

No

525f49cc-87c4-4655-b79c-4c4f971b1ad1

A random string generated by the application. We recommend that you set a string with more than 32 characters in length. The state value is returned to the application in a subsequent step. The application verifies whether the state value is the same as the initial value the application sends to the authorization endpoint. This ensures the request comes from the same session to prevent the Cross-Site Request Forgery (XSRF) security vulnerability. We recommended that you set a value for the parameter.

2.3. Log on to IDaaS

If the request sent to the authorization endpoint is successful, the user is redirected to the IDaaS logon page.

image

The user can complete authentication by using a configured logon method. IDaaS supports various logon methods with different security levels, including logon by scanning QR codes with DingTalk and logon with SMS verification code. For more information, see Logon methods.

When the logon is successful, a 302 redirect is initiated to redirect the browser to the specified redirect_uri, which is returned along with the code and state parameters.

Example:

{{redirect_uri}}?
  code=CO***&
  state=525f49cc-***

Parameter

Example

Description

code

COE59pkCTm4A9nmowJUsfsfarGEaiShj3TuDc7NCzLCYu9

The authorization code. The application uses the authorization code in the request it sends to IDaaS for an access token.

state

525f49cc-87c4-4655-b79c-4c4f971b1ad1

Ensure that the state value received by the application is the same as the initial value the application sends to the authorization endpoint.

2.4. Send a request to the token endpoint

After the application receives the authorization code in the previous step, it uses the authorization code to send a POST request to the token endpoint.

The steps to view the token endpoint are the same as those to view the authorization endpoint. Click Applications in the left-side navigation pane, click the application you want to manage on the Applications page, click the Sign-In tab, and then view the token endpoint in Application Settings.

Sample request:

POST /v2/<instance_id>/<app_id>/oauth2/token HTTP/1.0
Host: eiam-api-cn-hangzhou.aliyuncs.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
  &code=n0esc3N*****5acc3f0ogp4
  &client_id=s6BhdR*****kqt3
  &client_secret=7Fjfp0ZBr1*****KtDRbnfVdmIw
  &redirect_uri=http%3A%2F%2Fwww.example.com%2Fsso%2Fcallback

Parameter

Required

Example

Description

grant_type

Yes

authorization_code

The value of this parameter is fixed as authorization_code.

code

Yes

n0es***5acc3f0ogp4

The authorization code returned in the previous step.

client_id

Yes

app_mihar***s3rj7r4e4

By default, IDaaS supports two API authentication methods to verify that the caller is trusted.

In the client_secret_post mode, you must pass client_id and client_secret as POST parameters to IDaaS for caller authentication. Note that if you perform the authentication by using a tool such as Postman, make sure that you choose the form-data format. By default, this mode is used.

If you need to use the client_secret_basic mode, pass parameters according to specifications.

client_secret

Yes

CSAuycr***vtqRozS1V1

Same as the parameter client_id.

redirect_uri

Yes

http%3A%2F%2Fwww.example.com%2Fsso%2Fcallback

The redirect_uri used in the previous step. According to the protocol requirements, the parameter must be passed again to ensure the continuity of request.

Sample response:

{
  "token_type": "Bearer",
  "access_token": "ATM4SoVDqWgUJHLu3Bg6qF2hccE6cvjKXiKdiJ2Dc8RJZSbzpBDXPZK3gPhGxQs16s3s7MsZ46fEyiYTWG7EGFKi9uzGjRALaRLecPutBLzzQQRVUt6pbuarCbq5hFRje6bzsrW4jTehhCtZM5JneEfcSQ2ViSDVZGNNtMKAA6v7kTeubZrTaWNzosNMyzGXoD4rqPBwF9FsYqwACQ4aJrt9NnS3NpgDKoMtqEQs5TfDsCYMKYmp7Z73F2BJz89jzN1utEbnuj3HnvyRQPCismDiXjS8EPvoUZBrUBMhrnzYmMcT9KmzKoC12sQjDRQYqgPVxQyMKwQKwwHWXV7stEXnoSt524GW8HVrF3WRsM2N1Ykod1irCz7ZasSwk3ZS5mtn6fcSp8NH8",
  "expires_in": 1200,
  "expires_at": 1644843164,
  "id_token": "eyJraWQiOiJLRVkyVHkxcUw2dTIxTkdLbWNjdjNqd2ZkMm5kbWd0UVBuYWciLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyX3V5dmVmb3RqbjdrcGJlamZteG9vczNydG1tIiwianRpIjoiand0X2FhYWFjN3h5aGNsYWM2YXFrZ3RqYXhzdGh3NXlvdG41ZDc3cG1raSIsImlzcyI6Imh0dHBzOi8vcHJlLWVpYW0tYXBpLWNuLWhhbmd6aG91LmFsaXl1bi1pbmMuY29tL3YyL2lkYWFzX2JxZ2xkdnpwcGEyYWw2aTZhYzVxemphcWpxL2FwcF9taHlsZ28zaWFpcmpxamR4NWVvcDZ1YWYzNC9vaWRjIiwiaWF0IjoxNjQ0ODQxOTY1LCJuYmYiOjE2NDQ4NDE5NjUsImV4cCI6MTY0NDg0MjI2NSwiYXVkIjoiYXBwX21oeWxnbzNpYWlyanFqZHg1ZW9wNnVhZjM0IiwiYXRfaGFzaCI6IlhIRWFHcE1vb005enZRWGFNekNORUEifQ.abebHwoSzOi92-QOKO_E38jyfxjzVLpRIK858UsOehe_GzBoKOEl1zQOSljBB7CwZCdQJpqI1rUxqQopwjvHRSfA-O4_cc4sXDpZYXodeVRXUiv1kYB1b4gZ-hStcE1eh_5jJj1dpoGPBsjTTHjp43EgDx1-8M-8ePF3zXZAfqxCjjroGgB9qXtSreRAIUh5ODViyHYRSAis7CNdP7jKG1dU1UNSGwXWNyRcgVaCqL05gCh0LhHrutMXDy8pcKzdXHQMMBaHF-rGkkGdlp4q9KqwjkpzakcWieRmPa2UUXLdQgK1Pgzc5F7mE-fvsvVfMYfh_JgRIadj-frOIRFChA"
}

The user is logged on to the application. You can use one of the following methods to obtain more identity information of the logged-on user and create the application-side logon state:

  1. Use the id_token in the response to obtain the user ID after verification.

  2. Use the access_token in the response to send a request to the IDaaS user endpoint to obtain the information of the logged-on user.

For more information, see the following section.

Important

The scope of user data you can obtain is specified by the scope parameter in the request sent to the authorization endpoint in Step 1.

2.5. Parse id_token by using a program

An id_token is a signature token in JSON Web Token (JWT) format that contains the user identity information. The id_token issued by IDaaS contains user data that is visible in plaintext after decryption and the signature.

You can copy the complete content of id_token to the website https://jwt.io to better understand the content.

Example:

{
  "kid": "KEY2Ty1qL6u21NGKmccv3jwfd2ndmgtQPnag",
  "alg": "RS256"
}.{
  "sub": "user_uyvefotjn7kpbejfmxoos3rtmm",
  "jti": "jwt_aaaac7xyhclac6aqkgtjaxsthw5yotn5d77pmki",
  "iss": "https://pre-eiam-api-cn-hangzhou.aliyun-inc.com/v2/idaas_bqgldvzppa2al6i6ac5qzjaqjq/app_mhylgo3iairjqjdx5eop6uaf34/oidc",
  "iat": 1644841965,
  "nbf": 1644841965,
  "exp": 1644842265,
  "aud": "app_mhylgo3iairjqjdx5eop6uaf34",
  "at_hash": "XHEaGpMooM9zvQXaMzCNEA",
  "name": "testuser",
  "preferred_username": "testuser",
}.[Signature]

Before you use the content to log on to the application, you must verify the signature to ensure that the token is issued by IDaaS, rather than another third party. This can ensure the security of the logon.

2.5.1. Obtain the public key for signature verification

Before you verify the signature, you must obtain the endpoint for the public key for signature verification that is openly distributed by IDaaS.

You can click Applications in the left-side navigation pane, click the application you want to manage on the Applications page, click the Sign-In tab, and then view the endpoint for the public key for signature verification in Application Settings.

The application can access this endpoint to obtain the public key information. You can also open this URL in a browser to view the public key information.

Example:

{
  "keys": [
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "kid": "KEYkYnc55GJjD6y7VeCTvT7So44RGDYdbfs",
      "n": "pXmYkIpy1vaNjTMclU86BQjfmDhjlqMAX8ySVvh9gO-nae4ayvG_aCRYQL3qGCpFLZYrG3Jjoa0ktCn8PTTRi-v4gP27T7u6bUy0GXTlh3eKE0v1LYB81nfqjF2uazlPwPR5yYOhhWcK-gMNByLfE3CnkDc1YGwA3dZmIz-ZjOCKy8xLaBuqjrvwn5tpMpAoYEEaH4jIm7unTdhbKEKspNR-UXKD8q9RppMh5Tn2sB6oPHlQANudJDgqSwEOevIrdmHU0Zqxrb9cscGH9hH0QjmYEu72yI8BVeliPo3jK6JIoqCIcj5K_t8BJlFQ9QLJ8_o9tmd3BFv5_LVsh4BKGw"
    }
  ]
}

Then, you can use the code to verify the signature and obtain the content of id_token.

2.5.2. Verify signature and log on

You can find the tool in the corresponding language by visiting https://jwt.io/libraries and use the tool in the code to verify signature and parse id_token.

The following example uses the Java library: org.bitbucket.b_c:jose4j.

Add Maven dependencies:

<dependency>
  <groupId>org.bitbucket.b_c</groupId>
  <artifactId>jose4j</artifactId>
  <version>0.7.12</version>
</dependency>

Sample code:

import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.JsonWebKeySet;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;

public class IdTokenTest {

    public static void main(String[] args) throws Exception {
        String issuer = "https://eiam-api-cn-hangzhou.aliyuncs.com/v2/idaas_padyrlux3mphrlsex4uonyqhxu/app_mkif4dwlpeh6dns4pxpzbasqmu/oidc";
        String appId = "app_mkif4*****pxpzbasqmu";
        // Set the public key for parsing id_token as shown in the following code.
        String jwkJson = "{\n"
                + "  \"keys\": [\n"
                + "    {\n"
                + "      \"kty\": \"RSA\",\n"
                + "      \"e\": \"AQAB\",\n"
                + "      \"use\": \"sig\",\n"
                + "      \"kid\": \"KEY2H82C2at57itnW4onT3p1ySjwH4nirjCk\",\n"
                + "      \"n\": \"w7Jl3fAUJp_9GuxV*****QsOA4lnXR5OD4kF4QbIeBiDiH8_MThrFi9k2MB6YMkSzf5JfIkpAS3JCqZ7k6Wooydp4pzaZNZAk3SGzdsa022RmAT"
                + "-Iayi4Yj6J9tSdTQCjwh2XkzzsIxA_Hla8rWiQ8Vhw1"
                +
                "-7QArgObfe67nSR7LxD55MFLxk9FU0*****RlGhrQGE_0LUuGWtCJG1r1e6aKquyswfxxAr3Rvj8QGIeJrG0R1Pv8m8d1_5OdULhB7149VqjM6D98WFjab0U2SNv0UlREZXTcS4p-2QNm_1egYRRpJEY_00FZqNSYsmErMGepYhO_61KoGqd8cphWQ\"\n"
                + "    }\n"
                + "  ]\n"
                + "}";
        String jwt = "eyJraWQiOiJLRVkySDgyQzJhdD*****uaXJqQ2siLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2Vy*****lmNjRjZjR3amFrbnBieGpjd3V1IiwianRpIjoiand0X2FhYWFkYWllYTc2eWg1cW0zcm11bnoyeGg0eHd5aTJzZHBoNjR6aSIsImlzcyI6Imh0dHBzOi8vZWlhbS1hcGktY24taGFuZ3pob3UuYWxpeXVuY3MuY29tL3YyL2lkYWFzX3BhZHlybHV4M21waHJsc2V4NHVvbnlxaHh1L2FwcF9ta2lmNGR3bHBlaDZkbnM0cHhwemJhc3FtdS9vaWRjIiwiaWF0IjoxNjUzNjMwMDQxLCJuYmYiOjE2NTM2MzAwNDEsImV4cCI6MTY1MzYzMDM0MSwiYXVkIjoiYXBwX21raWY0ZHdscGVoNmRuczRweHB6YmFzcW11IiwibmFtZSI6InRlc3QiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ0ZXN0IiwidXBkYXRlZF9hdCI6MTY1MzYyODU5MH0.pAsUNB8OkdpIxJMZRfLJ7Pa31tsJyl44a1jVIlvdQxwOtPULAwrFxnB0X3eQx89hUGCdvYWl9FO9o-5kT7L-RER0wJYz9YNKqrVNBnaRwINRZyeYLRVurWMMzODQz-V0ULd9raM1M_i2f_SoWFs1gPFtYh_ijUARHISi7Q3q93ZfAuY8Lq2Nq07QunmDbosvioUd5wJG7WCxW5XXZYDUQe9p5IEYd1MSvnWuTOLbg7rKn0Vm4dNYGWjz1WuoAyCsc_QxOCqpmQ_2czoqPeN-SvPJAQ2CykLk7DSnGpABw1aNrjDidLS9Beqsga9VDCth86sk_0lyTZOaORtUrfVTtQ";

        JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwkJson);
        JwtConsumer jwtConsumer = createJwtConsumer(jsonWebKeySet, issuer, appId);

        JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
        // Signature verification is complete. The user information contained in id_token is output.
        System.out.println(jwtClaims);
    }

    // The method used by the signature verification tool.
    public static JwtConsumer createJwtConsumer(JsonWebKeySet jsonWebKeySet, String issuer, String appId) {
        final JwtConsumerBuilder jwtConsumerBuilder = new JwtConsumerBuilder();
        jwtConsumerBuilder.setExpectedIssuer(issuer);
        jwtConsumerBuilder.setRequireIssuedAt();
        jwtConsumerBuilder.setRequireExpirationTime();
        jwtConsumerBuilder.setAllowedClockSkewInSeconds(60);
        jwtConsumerBuilder.setExpectedAudience(appId);
        jwtConsumerBuilder.setVerificationKeyResolver((jws, nestingContext) -> {
            final String signKeyId = jws.getKeyIdHeaderValue();
            for (JsonWebKey jsonWebKey : jsonWebKeySet.getJsonWebKeys()) {
                if (signKeyId.equals(jsonWebKey.getKeyId())) {
                    return jsonWebKey.getKey();
                }
            }
            throw new RuntimeException("Cannot find verification key: " + signKeyId);
        });
        return jwtConsumerBuilder.build();
    }
}

The following code provides a sample output:

JWT Claims Set:{sub=user_dt6kj6yf64cf4wjaknpbxjcwuu, 
                jti=jwt_aaaadaiea76yh5qm3rmunz2xh4xwyi2sdph64zi, 
                iss=https://eiam-api-cn-hangzhou.aliyuncs.com/v2/idaas_padyrlux3mphrlsex4uonyqhxu/app_mkif4dwlpeh6dns4pxpzbasqmu/oidc, 
                iat=1653630041, 
                nbf=1653630041, 
                exp=1653630341, 
                aud=app_mkif4dwlpeh6dns4pxpzbasqmu, 
                name=test, 
                preferred_username=test, 
                updated_at=1653628590
               }

In this way, the application obtains the identity information of the logged-on user in IDaaS and uses the information for logon.

2.6. Obtain the user information from the UserInfo endpoint

You can also obtain user information from the UserInfo endpoint.

You can click Applications in the left-side navigation pane, click the application you want to manage on the Applications page, click the Sign-In tab, and then view the endpoint for the public key for signature verification in Application Settings.

The request for user information uses the standard RFC6750. Sample request:

GET /v2/<instance_id>/<app_id>/oauth2/userinfo HTTP/1.0
Host: eiam-api-cn-hangzhou.aliyuncs.com
Authorization: Bearer <AccessToken>

Sample response:
{
    "sub": "user_dt6kj6yf64cf4wjaknpbxjcwuu",
    "name": "test",
    "preferred_username": "test",
    "updated_at": 1653899948
}

Note

The characters returned by the UserInfo endpoint are consistent with the parameters in id_token. This means that the parameters configured in extended id_token are also returned from the UserInfo endpoint.

3. Other advanced settings

If you have an in-depth understanding of the OIDC protocol, you may use the following concepts or capabilities.

3.1. OIDC discovery endpoint

The issuer of an OIDC-based application is the unique identifier of the token issuer (IDaaS). It uses the following format:

https://<idaas-api-domain>/v2/<instance_id>/<application_id>/oidc

The following table describes the parameters in the angle brackets:

Parameter

Description

Example

idaas-api-domain

User portal URL.

https://nfaaacn.aliyunidaas.com

instance_id

The ID of the instance.

idaas_maaaaaaaaaaar2ed22e6m

application_id

The ID of the application.

app_maaaaaaaaaaaaaaajy6rbau

IDaaS supports OpenID Connect Discovery 1.0 standard. The OIDC discovery endpoint URL of the application is generated by suffixing /.well-known/openid-configuration to the issuer.

You can discover the following endpoint information by sending a request to the discovery endpoint. You can access all request endpoints in Application Settings.

Endpoint

Description

authorization_endpoint

Authorization endpoint

device_authorization_endpoint

Device mode Only OIDC-based applications support this feature. Custom applications do not support logon with device flow.

token_endpoint

Token endpoint

revocation_endpoint

Token revocation endpoint

userinfo_endpoint

UserInfo endpoint

jwks_uri

JWK public key endpoint

3.2. Mapping between the parameter values accessible to applications and specified scope

The following table lists the user information in id_token for OIDC-based applications when scope is specified.

Parameter

scope

Description

sub

openid

The userId of the user.

jti

openid

The token in JWT format. This is an auxiliary parameter.

iss

openid

Issuer of the JWT token. This is an auxiliary parameter.

iat

openid

The time when the JWT token was issued. This is an auxiliary parameter.

nbf

openid

The start time of the validity period of the JWT token. This is an auxiliary parameter.

exp

openid

The expiration time of the JWT token. This is an auxiliary parameter.

aud

openid

The ClientID of the application. This is an auxiliary parameter.

at_hash

openid

The hash value of AccessToken. This is an auxiliary parameter.

phone_number

phone

The mobile number of the user, such as +86 130 1234 5678.

phone_number_verified

phone

Whether the mobile number is verified. By default, the mobile number is verified.

email

email

The email address of the user, such as al***@example.com.

email_verified

email

Whether the email address is verified. By default, the email address is verified.

name

profile

The display name of the user.

preferred_username

profile

The username of the user.

updated_at

profile

The time when the profile of the user was last updated.

3.3. Authentication methods supported by the token endpoint

According to the OIDC protocol, IDaaS provides flexibility and supports the following four authentication methods.

The parameter token_endpoint_auth_methods_supported returned in the discovery endpoint specifies the supported authentication methods.

Value

Description

none

Used for Public clients. If the authentication method is none, grant_type cannot be client_credentials.

client_secret_basic

This authentication method is implemented according to RFC 6749 - The OAuth 2.0 Authorization Framework.

client_secret_post

This authentication method is implemented according to RFC 6749 - The OAuth 2.0 Authorization Framework.

client_secret_jwt

This authentication method is implemented according to OpenID Connect Core 1.0.

After the application receives the authorization code in the previous step and verifies that the request is valid (verifies that the state value is the same as the initial value the application sends to the authorization endpoint when it sends the request), the application uses the authorization code to send a POST request to the token endpoint.

The following example shows a request sent to the token endpoint by using the client_secret_basic authentication method.

POST /token HTTP/1.0
Host: api.aliyunidaas.com
Authorization: Basic YXBwX21pY2hzN3I0*******cHllOkNTKioqKioq

grant_type=authorization_code&
code=COE59pkCTm4J*******arGEaiShj7NCzLCYu9

For more information, see the OIDC Core 1.0 specifications.

3.4. Rotation of client secret of applications

For more information, see General settings.

Relevant standards