Hologres RAM角色授权模式

本文为您介绍如何使用角色SSO的方式访问Hologres。

背景信息

阿里云支持企业用户通过在阿里云控制台输入账号、密码后登录阿里云来管理和使用云资源。随着企业安全监管要求的日益严格,部分企业更愿意通过角色登录(Role Base_SSO)的方式登录阿里云。详情请参见SAML角色SSO概览

适用场景

一般情况下,对于阿里云企业用户,需要用户通过在阿里云控制台输入账号、密码后登录阿里云来管理和使用云资源。但是随着企业安全监管要求的日益严格,希望集中管理登录鉴权信息,企业往往会选择单点登录(SSO)的方式登录应用。SSO是指在多个应用系统中,用户只需要登录一次,就可以访问所有相互信任的应用系统。现在Hologres支持基于角色的SSO登录模式,详情请参见SAML角色SSO概览。基于该功能,您可以使用企业账号,扮演RAM角色访问Hologres实例。具体的访问权限由RAM角色控制。一个调用的样例如下。适用场景

  1. 用户使用浏览器在Idp的登录页面中选择阿里云作为目标服务。

    例如:如果企业IdP使用AD FS(Microsoft Active Directory Federation Service),则登录URL为:https://ADFSServiceName/adfs/ls/IdpInitiatedSignOn.aspx。

    说明

    有些IdP会要求用户先登录,再选择代表阿里云的SSO应用。

  2. IdP生成一个SAML响应并返回给浏览器。

  3. 浏览器重定向到SSO服务页面,并转发SAML响应给SSO服务。

  4. SSO服务使用SAML响应向阿里云STS服务请求临时安全凭证,并生成一个可以使用临时安全凭证登录阿里云控制台的URL。

    说明

    如果SAML响应中包含映射到多个RAM角色的属性,系统将会首先提示用户选择一个用于访问阿里云的角色。

  5. SSO服务将URL返回给浏览器。

  6. 浏览器重定向到该URL,以指定RAM角色登录到阿里云控制台,用户使用企业账户扮演RAM角色登录Hologres实例。

Hologres支持的用户访问方式

Hologres支持如下两种访问方式:

  • 通过云账号(阿里云账号或RAM用户)访问Hologres。

    您可以通过输入账号、密码的方式登录阿里云管理控制台,并以当前登录账号的身份使用Hologres。此时,阿里云账号将成为Hologres某个实例的成员,拥有Hologres产品的使用权限。

  • 通过RAM角色SSO的方式登录Hologres。

    您也可以通过角色SSO的方式(SAML角色SSO概览)登录阿里云,并使用Hologres。此时,阿里云访问控制角色(RAM Role)将成为Hologres某个实例的成员,扮演该RAM Role的使用者将拥有和云账号类成员同样的产品使用权限。RAM角色的描述,详情请参见RAM角色概览

对于Hologres来说,RAM角色(RAM Role)和阿里云账号(包括主账号和RAM用户)是同等地位的账号。因此,对于Hologres来说,RAM角色就是一个普通的可登录账号。Superuser需要对这个RAM角色(而不是背后的云账号)进行授权来赋予这个RAM角色权限(SELECT/INSERT/UPDATE等),这个RAM角色才能在权限范围内使用Hologres。

RAM角色SSO(STS)介绍

通过RAM角色SSO的方式登录并访问Hologres是基于阿里云STS服务实现的。阿里云STS(Security Token Service)是为阿里云账号(或RAM用户)提供短期访问权限管理的云服务。通过STS,您可以为用户(您的本地账号系统所管理的用户)颁发一个自定义时效和访问权限的访问凭证。用户可以使用STS短期访问凭证直接连接Hologres并访问被授权的资源。

使用STS Token有以下优势:

  • 减少了账号AccessKey IDAccessKey Secret泄露的风险,只需要生成一个临时访问凭证给用户使用即可。

  • 能使用灵活的权限控制,STS Token有一定的时间期限,不需要关心权限撤销问题,临时访问凭证过期后会自动失效。

步骤一:创建RAM角色

登录访问控制,创建RAM角色。当前可信实体类型,可以选择阿里云账号或者身份提供商。

通过RAM用户扮演角色并添加权限

如果需要通过RAM用户来扮演RAM角色并基于阿里云控制台切换身份方式扮演该角色,请登录访问控制,创建RAM角色。当前可信实体类型,可以选择阿里云账号

  1. 创建可信实体类型为阿里云账号RAM角色。

    1. 登录访问控制,在左侧导航栏,单击身份管理>角色

    2. 角色页面,单击创建角色,当前可信实体类型选择阿里云账号

    3. 单击下一步,配置角色名称,并选择当前云账号

    4. 单击完成,页面提示角色创建成功完成创建。

  2. 创建并添加权限策略。

    1. RAM角色管理列表页,单击目标角色名称,进入角色信息详情页。

    2. 选择信任策略页签,单击编辑信任策略修改信任策略为如下脚本内容。

      • 参数说明

        在策略配置时,您需要将如下脚本中的acs:ram::主账号ID:root信息中的主账号ID,替换为需要授权的账号信息。请前往用户信息页面,获取账号ID。

      • 脚本配置

        {
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "RAM": [
                            "acs:ram::主账号ID:root"
                        ]
                    }
                },
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                            "dataworks.aliyuncs.com"
                        ]
                    }
                }
            ],
            "Version": "1"
        }
    3. 单击保存信任策略,完成权限策略配置。

  3. 创建RAM用户并授予角色权限。

    通过RAM用户来扮演RAM角色,需要创建一个RAM用户并授予扮演角色的权限。

    1. 登录访问控制,在左侧导航栏选择身份管理 > 用户

    2. (可选,如果您已经存在RAM用户,可跳过该步骤。)单击创建用户,可一次性创建多个RAM用户。创建RAM用户详情请参见创建RAM用户

    3. 单击目标RAM用户操作列的添加权限

    4. 添加权限页面,为已创建的RAM用户添加AliyunSTSAssumeRoleAccess权限,获取调用STS服务AssumeRole接口的权限。设置STS权限

    5. 单击确定,完成角色设置。

通过IDP身份提供商账号来扮演角色并添加权限

如果需要通过本地IDP身份提供商账号登录至阿里云扮演RAM角色,请登录访问控制,创建RAM角色。当前可信实体类型,可以选择身份提供商

  1. 创建可信实体类型为身份提供商RAM角色。

    1. 登录访问控制在左侧导航栏,单击身份管理 > 角色

    2. 角色页面,单击创建角色,当前可信实体类型选择身份提供商

    3. 单击下一步,配置角色名称备注

    4. 选择身份提供商类型选择身份提供商并查看限制条件后,单击完成,页面提示角色创建成功完成创建。

  2. 创建并添加权限策略。

    1. 在角色列表页,单击目标角色名称,进入角色信息详情页。

    2. 选择信任策略页签,单击编辑信任策略,修改新任策略为如下脚本内容。

      • 参数说明

        在策略配置时,您需要将如下脚本中的acs:ram::主账号ID:saml-provider/IDP信息中的主账号ID,替换为需要授权的账号信息。请前往用户信息页面,获取账号ID。

      • 脚本配置

        "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Condition": {
                        "StringEquals": {
                            "saml:recipient": "https://signin.aliyun.com/saml-role/sso"
                        }
                    },
                    "Effect": "Allow",
                    "Principal": {
                        "Federated": [
                            "acs:ram::主账号ID:saml-provider/IDP"
                        ]
                    }
                },
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                            "dataworks.aliyuncs.com"
                        ]
                    }
                }
            ],
            "Version": "1"
        }
        }
    3. 单击保存信任策略,完成权限策略配置。

步骤二:添加RAM角色至Hologres实例并授权

RAM角色需要有Hologres实例的开发权限,才能在权限范围内使用Hologres。由于RAM角色默认没有Hologres管控台的查看和操作实例的权限,因此需要主账号完成RAM相关权限授予才能进行后续操作。具体操作,请参见授予RAM用户权限。添加RAM角色至Hologres实例,您可以通过如下方式进行授权。

  1. 登录Hologres管理控制台进行授权。

    1. 在左侧导航栏选择进入实例列表页面,单击需要授权的实例,在用户管理页签找到RAM角色并新增用户至实例。

    2. DB管理页签,为该RAM用户授予具体的实例开发权限。

  2. 通过SQL方式授权。

    您可以通过SQL方式进行授权,具体请参见权限管理概述

  3. 若是通过RAM用户扮演RAM角色,RAM角色默认没有Hologres管理控制台的权限,需要主账号给RAM用户在访问控制页面授予AliyunRAMReadOnlyAccess权限,否则RAM角色无法在Hologres管理控制台进行任何操作。详情请参见文档授予RAM用户权限

步骤三:登录阿里云并使用Hologres

管控台登录和HoloWeb登录

当您完成授权之后,使用者就可以扮演user-role角色登录并使用Hologres。

  1. 使用RAM角色,登录Hologres管理控制台,对Hologres实例进行管控。

  2. Hologres控制台页面,单击左侧导航栏前往HoloWeb,进入HoloWeb页面,进行Hologres结构设计和数据开发。具体操作请参见连接HoloWeb并执行查询

JDBCPSQL客户端登录

Hologres V2.0版本开始,Hologres支持在PostgreSQL协议的连接选项中指定Security Token。您可以凭借Security Token,通过PostgreSQL客户端,如JDBCPSQL,实现RAM角色登录访问Hologres。

在访问Hologres之前,您需要先确认已完成下述两项操作:

确认完成操作后,您可以通过以下方式连接并使用Hologres。

  • JDBC JAVA连接方式:更多操作信息,详情请参见JDBC连接Hologres

    • 示例代码1:通过PostgreSQL JDBC Driver自带的PGProperty类的属性来加载STS Token三元组完成身份校验。

      import org.postgresql.PGProperty;
      import java.sql.*;
      import java.io.IOException;
      import java.util.Properties;
      
      public class JdbcLinkHologres1 {
          public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
               // 此处以把AccessKeyAccessKeySecret保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里
      	// 强烈建议不要把AccessKeyAccessKeySecret保存到代码里,会存在密钥泄漏风险
              String accessKeyId = "ALIBABA_CLOUD_ACCESS_KEY_ID";
              String accessKeySecret = "ALIBABA_CLOUD_ACCESS_KEY_SECRET";
              String securityToken = "<SecurityToken>";
              String url = "jdbc:postgresql://<host>:<port>/<database>";
      
              Properties props = new Properties();
              PGProperty.USER.set(props, accessKeyId);
              PGProperty.PASSWORD.set(props, accessKeySecret);
              PGProperty.OPTIONS.set(props, "sts_token=" + securityToken);
      
              Class.forName("org.postgresql.Driver");
              Connection connection = DriverManager.getConnection(url, props);
      
              Statement statement = connection.createStatement();
              ResultSet resultSet = statement.executeQuery("SELECT * FROM tabletest");
              // Process the resultSet
              while (resultSet.next()) {
                  System.out.println("Result: " + resultSet.getInt(1));
                  System.out.println("Result: " +  resultSet.getString(2));
              }
          }
      }
    • 示例代码2:通过先对SecurityToken信息进行URL编码然后拼接至JDBCURL中,再通过驱动类获取Hologres链接时加载AccessKeyIdAccessKeySecret进行身份验证。

      import java.net.URLEncoder;
      import java.sql.*;
      import java.io.IOException;
      
      public class JdbcLinkHologres2 {
          public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
              // 此处以把AccessKeyAccessKeySecret保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里
      	// 强烈建议不要把AccessKeyAccessKeySecret保存到代码里,会存在密钥泄漏风险
              String accessKeyId = "ALIBABA_CLOUD_ACCESS_KEY_ID";
              String accessKeySecret = "ALIBABA_CLOUD_ACCESS_KEY_SECRET";
              String securityToken = "<SecurityToken>";
                          
              String url = "jdbc:postgresql://<host>:<port>/<database>";
              String urlWithOptions = url + "?options=sts_token=" + URLEncoder.encode(securityToken, "UTF-8");
      
              Class.forName("org.postgresql.Driver");
              Connection connection = DriverManager.getConnection(urlWithOptions, accessKeyId, accessKeySecret);
      
              Statement statement = connection.createStatement();
              ResultSet resultSet = statement.executeQuery("SELECT * FROM tabletest");
      
              // Process the resultSet
              while (resultSet.next()) {
                  System.out.println("Result: " + resultSet.getInt(1));
                  System.out.println("Result: " +  resultSet.getString(2));
              }
          }
      }
  • PSQL客户端连接方式:Linux系统语句如下。更多操作信息,详情请参见PSQL客户端连接Hologres

    PGUSER=<AccessKeyId> PGPASSWORD=<AccessKeySecret> PGOPTIONS="sts_token=<SecurityToken>" psql -h <host> -p <port> -d <database>

常见问题

RAM角色登录报错password authentication failed for user "<AccessKeyId>",应当如何排查?

该错误表示可能存在AccessKeyId错误、AccessKeySecret错误、Security Token错误,或当前登录的用户尚未在Hologres实例中创建。建议按照以下顺序进行排查:

  1. 检查实例内是否存在当前正在登录的用户。若不存在,可将RAM角色新增至该实例。详情请参见步骤二:添加RAM角色至Hologres实例并授权

  2. 检查Security Token传递方式是否正确,当通过URL进行传递时,需要经过URLEncoder.encode处理。

  3. 检查AccessKeyId、AccessKeySecretSecurity Token是否正确无误。