Embed a logon-free URL in your R&D or tool platform so users can access Data Management (DMS) without logging on with an Alibaba Cloud account or as a Resource Access Management (RAM) user.
How it works
The flow uses temporary identity credentials from Security Token Service (STS) to generate a short-lived SigninToken, which you exchange for a logon-free URL that redirects users directly into the DMS console.
A RAM user calls the
AssumeRoleoperation to get temporary credentials (AccessKey ID, AccessKey secret, and security token) for a RAM role that has DMS access.Your application exchanges those temporary credentials for a SigninToken by calling
GetSigninToken.Your application appends the SigninToken to a federation URL to produce the final logon-free URL.
The user's browser opens the logon-free URL and lands directly in the DMS console—no Alibaba Cloud account required.
Each SigninToken is single-use. Generate a new one for each logon-free URL you create.
Treat the logon-free URL as a secret. Return it to the client over a secure connection using an HTTP 302 redirect—never expose it in logs or client-side code.
Prerequisites
Before you begin, ensure that you have:
A RAM role configured for DMS access, with either
AliyunDMSReadOnlyAccessorAliyunDMSFullAccessgranted. See Create a RAM role for a trusted Alibaba Cloud account and Grant permissions to a RAM role.A RAM user with the
AliyunSTSAssumeRoleAccesspermission. See Create a RAM user and Grant permissions to the RAM user.The
aliyun-java-sdk-stsandaliyun-java-sdk-corelibraries added to your project.
Step 1: Get temporary credentials
Call the AssumeRole operation as the RAM user to get temporary credentials for the RAM role. These credentials are valid for 900 to 3,600 seconds (default: 3,600).
For the full API reference, see AssumeRole.
/**
* Calls AssumeRole to get temporary credentials for the specified RAM role.
*
* @param accountId Your Alibaba Cloud account ID
* @param accessKeyId The RAM user's AccessKey ID
* @param accessKeySecret The RAM user's AccessKey secret
* @param ramRole The name of the RAM role to assume
*/
private static AssumeRoleResponse.Credentials assumeRole(
String accountId, String accessKeyId, String accessKeySecret, String ramRole)
throws ClientException {
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
AssumeRoleRequest request = new AssumeRoleRequest();
// ARN format: acs:ram::<accountId>:role/<ramRole>
request.setRoleArn(getRoleArn(accountId, ramRole));
// Identifies this session in audit logs. Format: ^[a-zA-Z0-9\.@\-_]+$
request.setRoleSessionName("session-name");
// Validity period in seconds. Valid values: 900-3600. Default: 3600.
request.setDurationSeconds(3600L);
AssumeRoleResponse response = client.getAcsResponse(request);
return response.getCredentials();
}The response contains the AccessKeyId, AccessKeySecret, SecurityToken, and Expiration fields. Pass all three credential values to Step 2.
Step 2: Get a SigninToken
Exchange the temporary credentials for a SigninToken by calling GetSigninToken.
/**
* Calls GetSigninToken to exchange temporary credentials for a SigninToken.
*
* @param accessKeyId Temporary AccessKey ID from Step 1
* @param accessKeySecret Temporary AccessKey secret from Step 1
* @param securityToken Security token from Step 1
*/
private static String getSignInToken(
String accessKeyId, String accessKeySecret, String securityToken)
throws IOException, URISyntaxException {
URIBuilder builder = new URIBuilder(SIGN_IN_DOMAIN);
builder.setParameter("Action", "GetSigninToken")
.setParameter("AccessKeyId", accessKeyId)
.setParameter("AccessKeySecret", accessKeySecret)
.setParameter("SecurityToken", securityToken)
.setParameter("TicketType", "normal");
HttpGet request = new HttpGet(builder.build());
CloseableHttpClient httpClient = HttpClients.createDefault();
try (CloseableHttpResponse response = httpClient.execute(request)) {
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String body = EntityUtils.toString(response.getEntity());
JSONObject json = JSON.parseObject(body);
return json.getString("SigninToken");
}
System.out.println(response.getStatusLine());
}
return null;
}About TicketType: The value you set here determines which DMS domain to use in the Destination parameter in Step 3.
TicketType value | DMS domain |
|---|---|
normal | http://dms.aliyun.com |
mini (BID virtual network operator) | http://dms-jst4service.aliyun.com or http://dms-Itwo4service.aliyun.com |
Step 3: Build the logon-free URL
Construct the logon-free URL by combining the SigninToken with the target DMS page.
The logon-free URL uses the following format:
http://signin.aliyun.com/federation?Action=Login
&LoginUrl=<Your redirect URL returning HTTP 302>
&Destination=<Target DMS page URL>
&SigninToken=<SigninToken from Step 2>The following Java method builds this URL:
/**
* Builds a logon-free URL for the specified DMS page.
*
* @param pageUrl The DMS page to redirect users to (e.g., https://dms.aliyun.com)
* @param signInToken The SigninToken obtained in Step 2
*/
private static String getDmsLoginUrl(String pageUrl, String signInToken)
throws URISyntaxException {
URIBuilder builder = new URIBuilder(SIGN_IN_DOMAIN);
builder.setParameter("Action", "Login")
// Your site must return HTTP 302 to redirect users to this URL.
.setParameter("LoginUrl", "https://signin.aliyun.com/login.htm")
// The DMS page the user lands on after authentication.
.setParameter("Destination", pageUrl)
.setParameter("SigninToken", signInToken);
HttpGet request = new HttpGet(builder.build());
return request.getURI().toString();
}Complete example
The following example ties all three steps together. Load credentials from environment variables rather than hardcoding them.
// RAM user credentials — load from environment variables, not source code.
String accountId = System.getenv("ALIBABA_CLOUD_ACCOUNT_ID");
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
String ramRole = System.getenv("DMS_RAM_ROLE_NAME");
// Step 1: Get temporary credentials by assuming the RAM role.
AssumeRoleResponse.Credentials credentials =
assumeRole(accountId, accessKeyId, accessKeySecret, ramRole);
System.out.println("Expiration: " + credentials.getExpiration());
System.out.println("Access Key ID: " + credentials.getAccessKeyId());
System.out.println("Access Key Secret: " + credentials.getAccessKeySecret());
System.out.println("Security Token: " + credentials.getSecurityToken());
// Step 2: Exchange temporary credentials for a SigninToken.
String signInToken = getSignInToken(
credentials.getAccessKeyId(),
credentials.getAccessKeySecret(),
credentials.getSecurityToken());
System.out.println("SigninToken: " + signInToken);
// Step 3: Build the logon-free URL for the DMS homepage.
String pageUrl = getDmsLoginUrl("https://dms.aliyun.com", signInToken);
System.out.println("Logon-free URL: " + pageUrl);Sample output:
Expiration: 2020-11-30T06:16:20Z
Access Key ID: STS.NT7L6Jp5Y8W9LNvGQku2x****
Access Key Secret: 4nU8F6rv8MCDR8tygMDnXvN9yCNBCVrxnqArj1n1****
Security Token: CAIS/gF1q6Ft5B2yfSjIr5e****...
SigninToken: 06ec409b9d8c48f6ac5dcd18a0513ee1dhUkhcRn5CMsDqffC4wxsuFt9xjYtYePmYTHEWSMVKLFyXXnSq3IUbon1v46wCmKPwrAejDvw2i8rilolPSuxpKRDxz****
Logon-free URL: http://signin.aliyun.com/federation?Action=Login&LoginUrl=https%3A%2F%2Fsignin.aliyun.com%2Flogin.htm&Destination=https%3A%2F%2Fdms.aliyun.com&SigninToken=06ec409b9d8c48f6ac5dcd18a0513ee1dhUkhcRn5CMsDqffC4wxsuFt9xjYtYePmYTHEWSMVKLFyXXnSq3IUbon1v46wCmKPwrAejDvw2i8rilolPSuxpKRDxzD****What's next
Open the logon-free URL in the user's browser to access the DMS console directly. Each SigninToken can only be used once—if you need a new logon-free URL, obtain a new SigninToken.