您可以通过给阿里云创建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";
        /**
         * 使用安全令牌获取登录令牌
         * https://help.aliyun.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接口获取用户临时身份
         * 参考 https://help.aliyun.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>