您可以通過給阿里云創建RAM用戶并授予STS權限策略,將DAS控制臺免登錄嵌套到自建的運維平臺中。本文將介紹相關操作步驟。

前提條件

已經創建RAM用戶并授予STS權限策略,詳情請參見配置RAM用戶授權

操作步驟

  1. 通過AssumeRole接口獲取用戶臨時身份。
    說明
  2. 使用安全令牌獲取登錄令牌。關于如何獲取登錄令牌,請參見GetSigninToken
    說明 TicketType主要分為normalmini
  3. 構造訪問DAS頁面免登錄鏈接。
    1. 構造URL格式如下:
      https://signin.aliyun.com/federation?Action=Login                      
      &LoginUrl=<登錄失效跳轉的地址,一般配置為自建WEB配置302跳轉的URL>                      
      &Destination=<實際訪問DAS服務頁面>                      
      &SigninToken=<獲取的登錄TOKEN>
      說明 Destination對應的DAS服務頁面,受到步驟二中的TicketType參數影響。
      • normal對應的DAS域名:https://hdm.console.aliyun.com
      • mini應用于BID虛商對應的DAS域名:https://hdm4service.console.aliyun.com
    2. 配置Destination。如果要嵌入DAS的監控大盤,Destination可以設置為:https://hdm.console.aliyun.com/?hideTopbar=true&isShare=true&hideMenu=true#/dashboard/convoy
      說明 #前面的isShare=truehideTopbar=true是必選參數。
      參數 說明
      isShare=true 外部控制臺嵌入需要。
      hideTopbar=true 隱藏DAS阿里云控制臺邊欄。
      hideMenu=true 隱藏DAS外部菜單。
      hideInstanceMenu=true 隱藏DAS實例詳情頁邊欄和外部邊欄。
      hideAutonomousButton=true 隱藏DAS自治功能開關。
    3. 參考代碼如下:
      private static String getHdmLoginUrl(String pageUrl, String signInToken) throws URISyntaxException {  
      URIBuilder builder = new URIBuilder(SIGN_IN_DOMAIN);  
      builder.setParameter("Action", "Login");  
      // 登錄失效跳轉的地址,一般配置為自建WEB配置302跳轉的URL  
      builder.setParameter("LoginUrl", "https://signin.aliyun.com/login.htm");  
      // 實際訪問DAS的頁面,比如全局大盤,實時大盤,某個實例詳情等  
      builder.setParameter("Destination", pageUrl);  
      builder.setParameter("SigninToken", signInToken);  
      HttpGet request = new HttpGet(builder.build());  
      return request.getURI().toString();}

附錄

  • 完整代碼:
    import java.io.IOException;
    import java.net.URISyntaxException;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.profile.IClientProfile;
    import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
    import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    /**
     * Created by tinker on 2019-07-09.
     *
     * @author tinker
     * @date 2019-07-09
     */
    public class StsService {
        private static String getRoleArn(String accountId, String roleName) {
            return String.format("acs:ram::%s:role/%s", accountId, roleName);
        }
        private static final String SIGN_IN_DOMAIN = "https://signin.aliyun.com/federation";
        /**
         * 使用安全令牌獲取登錄令牌
         * http://bestwisewords.com/document_detail/91913.html
         *
         * @param accesskeyId
         * @param accessKeySecret
         * @param securityToken
         * @return
         * @throws IOException
         * @throws URISyntaxException
         */
        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 context = EntityUtils.toString(response.getEntity());
                    JSONObject jsonObject = JSON.parseObject(context);
                    return jsonObject.getString("SigninToken");
                } else {
                    System.out.println(response.getStatusLine());
                }
            }
            return null;
        }
        private static String getHdmLoginUrl(String pageUrl, String signInToken) throws URISyntaxException {
            URIBuilder builder = new URIBuilder(SIGN_IN_DOMAIN);
            builder.setParameter("Action", "Login");
            // 登錄失效跳轉的地址,一般配置為自建WEB配置302跳轉的URL
            builder.setParameter("LoginUrl", "https://signin.aliyun.com/login.htm");
            // 實際訪問DAS的頁面,比如全局大盤,實時大盤,某個實例詳情等
            builder.setParameter("Destination", pageUrl);
            builder.setParameter("SigninToken", signInToken);
            HttpGet request = new HttpGet(builder.build());
            return request.getURI().toString();
        }
        /**
         * 通過AssumeRole接口獲取用戶臨時身份
         * 參考 http://bestwisewords.com/document_detail/28763.html
         *
         * @param accountId
         * @param accessKeyId
         * @param accessKeySecret
         * @param ramRole
         * @return
         * @throws ClientException
         */
        private static AssumeRoleResponse.Credentials assumeRole(String accountId, String accessKeyId,
                                                                 String accessKeySecret, String ramRole)
            throws ClientException {
            String defaultRegion = "cn-hangzhou";
            IClientProfile profile = DefaultProfile.getProfile(defaultRegion, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            AssumeRoleRequest request = new AssumeRoleRequest();
            // 設置RAMArn, accountId為資源Owner的UID,即主賬號
            request.setRoleArn(getRoleArn(accountId, ramRole));
            // 用戶自定義參數。此參數用來區分不同的令牌,可用于用戶級別的訪問審計。格式:^[a-zA-Z0-9\.@\-_]+$
            request.setRoleSessionName("session-name");
            // 指定的過期時間,單位為秒。過期時間范圍:900 ~ 3600,默認值為:3600
            request.setDurationSeconds(3600L);
            AssumeRoleResponse response = client.getAcsResponse(request);
            return response.getCredentials();
        }
        public static void main(String[] args) throws IOException, URISyntaxException {
            try {
                /*
                Step 0 準備子賬號和權限授權
                 */
                String accountId = "";
                // 用來訪問 DAS 產品的Role,可以按照需要添加AliyunHDMReadOnlyAccess(只讀),AliyunHDMFullAccess權限
                String ramRole = "";
                //  某個子賬號AK,SK,要求需要有AliyunSTSAssumeRoleAccess權限
                String accessKeyId = "";
                String accessKeySecret = "";
                /*
                 Step 1 通過AssumeRole接口獲取臨時AK,SK,SecurityToken
                 */
                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 獲取SigninToken
                 */
                String signInToken = getSignInToken(credentials.getAccessKeyId(),
                    credentials.getAccessKeySecret(),
                    credentials.getSecurityToken());
                System.out.println("Your SigninToken is: " + signInToken);
                /*
                Step 3 構造免登錄鏈接,比如DAS的監控大盤
                 */
                String pageUrl = getHdmLoginUrl("https://hdm.console.aliyun.com/?hideTopbar=true#/customDashboard?", signInToken);
                System.out.println("Your PageUrl is : " + pageUrl);
            } catch (ClientException e) {
                System.out.println("Failed:");
                System.out.println("Error code: " + e.getErrCode());
                System.out.println("Error message: " + e.getErrMsg());
                System.out.println("RequestId: " + e.getRequestId());
            }
        }
    }
  • POM 文件:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.aliyun</groupId>
        <artifactId>hdm-login-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>3.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-sts</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.9</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
    </dependencies>
        <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
        </build>
    </project>