全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

临时授权访问

最近更新时间:2024-09-20 21:08:19

基本原理

KS3主账号或IAM子用户都可以长期正常使用,对应的AK/SK发生泄露后如果无法及时解除权限会存在数据安全风险。如果众多的客户端需要直接与KS3交互,可以让客户端获取一个临时的、有指定生效时长的最小权限的凭证(即临时身份凭证),从而最大程度上保护用户数据安全。

案例描述

客户开发的APP会分发给终端用户,终端用户的数据需要直接上传到KS3,如果将主账号或者IAM子用户的AK/SK嵌入到APP都是非常危险的行为。以下方法可以解决此类问题,安全地授权给众多的APP用户上传数据,保证多个用户之间存储的隔离。

类似这种需要临时访问的场景可以使用临时身份凭证来解决,其主要操作步骤如下所示:

  1. 在当前的主账号下创建一个角色,指定角色授信的主账户,并且给角色通过用户策略(User Policy)授予一个最小权限。

  2. 然后在授信主账号下创建一个子用户,并授权给子用户角色(让这个子用户扮演这个角色),子用户就可以通过STS服务获取临时AK/SK及token,去访问KS3了,为了提升安全性该token还有一定的过期时间。

    授信账号(又叫载体信息)可以是当前主账号,也可以是其他主账号。比如您在账号1下创建角色授信给账号2,则账号2的子用户就可以扮演账号1下的角色。

原理图如下所示:

1.png

具体步骤

1. 创建角色

1. 进入KS3控制台,点击左侧导航栏下方的访问控制(或点击右上角账号名称下拉框里的访问控制),点击左侧导航栏下方的角色管理,进入角色管理界面。

2. 点击新建角色按钮,选择金山云账号。假设创建一个名为test-role的角色,设置载体信息为当前账号(也可以选择其他账号,载体信息即授信账号,比如您在账号1下创建角色授信给账号2,则账号2的子用户就可以扮演账号1下的角色)。新创建的角色是没有任何权限的,点击下一步来设置角色权限(如果需要设置自定义策略,需要在创建角色前完成自定义策略的创建,详见新建自定义策略),设置结束后点击完成

1. 如果需要给角色授予自定义策略,需要先创建自定义策略后再创建角色。因为创建角色的同时也需要授权,否则无法创建角色。

2. 如果创建角色后还需要授予该角色其他权限,参考授予角色访问KS3的权限

2. 授予角色访问KS3的权限

创建角色后,如果后续还需要为角色增加其他自定义策略,执行以下操作步骤。

2.1 新建自定义策略
  1. 点击策略自定义策略新建策略,假设设置名称为“role-test-policy”,设置策略类型为可视化配置 ,点击添加策略语句

  1. 选择产品类型为对象存储,根据需求选择对应的操作,支持对所有资源特定资源授权,点击确定,点击创建策略。至此角色策略创建完成。

    1. 如果需要列出某个Bucket下所有文件的权限,需要同时设置查询Bucket列表和查询Bucket ACL的权限。

    2. 选择可视化配置时,可以对所有资源授予权限,也可以对特定资源授予权限(如某个Bucket),填写特定资源信息方式参见文档:资源说明

    3. 除了可视化配置方式新建策略,用户也可以通过策略语法方式新建策略,有关用户策略的更多详情请参见文档:用户策略

2.2 将权限授予角色

创建完角色之后,回到角色管理页面,点击刚刚创建的角色名,进入角色详情页。点击关联策略添加授权,弹出添加权限弹窗。在策略下拉框中选择自定义策略,选择策略role-test-policy,点击确定按钮。这样角色test-role就具有了相应的权限。

注意角色管理页面需要记录下角色的KRN字段

3. 子用户扮演角色访问KS3

3.1 创建扮演角色权限
  1. 进入KS3控制台,点击左侧导航栏最下方中的访问控制(或点击右上角账号名称下拉框里的访问控制),进入访问控制管理页面,点击左侧导航栏中权限管理策略,进入策略管理页面,选择自定义策略新建策略

  1. 在新建策略中,输入策略名,此处假设为"test-policy",然后选择 可视化配置添加策略语句

  1. 侧边弹出添加策略语句弹窗,产品服务下拉框中选择临时身份验证,在操作中选择获取角色的一个临时安全令牌*,该权限表示可以扮演角色,点击确定创建策略,至此子用户策略创建完成。

3.2 将扮演角色权限授予子用户

主账户是不能扮演角色的,需要受信主账户通过用户权限(User Policy)把扮演角色的权限授权给IAM子用户。

  1. 子用户页面选中刚创建的子用户,点击右侧添加权限来为子用户授权。

主账户是不能扮演角色的,需要子账号来扮演角色。如果没有子用户,需要先创建一个子用户。创建步骤参见文档:子账号授权访问

  1. 选择权限的下拉框中选择自定义策略,选中在创建策略步骤中创建的test-policy策略,点击确定,至此子用户就具有了扮演角色的权限。

3.3 子用户扮演角色访问KS3

至此该子用户仅具有了扮演角色的权限,但还没有关联具体的角色,因此还需要添加权限对应的资源,即角色ID。点击导航栏左侧策略页签,点击自定义策略,点击所创建的test-policy策略名称(即创建的扮演角色策略),在策略内容中的Resource字段值中填入角色的KRN

角色的KRN在角色角色管理→点击角色名称,进入角色详情页面查看。

使用STS授权访问

  1. 使用子用户test-subuser的AK/SK 去调用STS服务获取临时权限。详见文档获取角色的临时身份

http://sts.cn-beijing-6.api.ksyun.com/?Action=AssumeRole
&Version=2019-11-01
&RoleSessionName=Bob
&RoleKrn=krn:ksc:iam::Account_ID:role/test-role
&AUTHPARAMS

返回的内容如下:

<AssumeRoleResponse>
  <AssumeRoleResult>
      <Credentials>
        <SecretAccessKey>wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY</SecretAccessKey>
        <Expiration>2017-07-15T23:28:33.359Z</Expiration>
        <AccessKeyId>AKIAIOSFODNN7EXAMPLE</AccessKeyId>
        <SecurityToken>V1xxxxxxxxxxxx</SecurityToken>
      </Credentials>
      <AssumedRoleUser>
         <Krn>krn:ksc:sts::123456789012:assumed-role/demo/Bob</Krn>
         <AssumedRoleId>ARO123EXAMPLE123:Bob</AssumedRoleId>
      </AssumedRoleUser>
   </AssumeRoleResult>
   <ResponseMetadata>
     <RequestId>c6104cbe-af31-11e0-8154-cbc7ccf896c7</RequestId>
   </ResponseMetadata>
</AssumeRoleResponse>
  1. 从返回的XML结果中找到临时权限:AccessKeyId、SecretAccessKey及SecurityToken,然后通过KS3 APIJAVA SDK去访问相应的资源。

GO示例:

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/KscSDK/ksc-sdk-go/ksc"
	"github.com/KscSDK/ksc-sdk-go/ksc/utils"
	"github.com/KscSDK/ksc-sdk-go/service/sts"
	"github.com/ks3sdklib/aws-sdk-go/aws"
	"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
	"github.com/ks3sdklib/aws-sdk-go/service/s3"
	"os"
)

func main() {
	ak := "<AccessKeyID>"
	sk := "<AccessKeySecret>"
	stsRegion := "cn-beijing-6"
	assumeRole := assumeRoleRequest(ak, sk, stsRegion) //调用ksc-go-sdk的sts服务
	var data Response
	_ = json.Unmarshal(assumeRole, &data)
	stsAk := data.AssumeRoleResult.Credentials.AccessKeyId      // sts ak
	stsSk := data.AssumeRoleResult.Credentials.SecretAccessKey  // sts sk
	stsToken := data.AssumeRoleResult.Credentials.SecurityToken // sts token

	//create ks3 client with sts ak,sk,token
	credentials := credentials.NewStaticCredentials(stsAk, stsSk, stsToken)
	client := s3.New(&aws.Config{
		Region:           "BEIJING",
		Credentials:      credentials,
		Endpoint:         "ks3-cn-beijing.ksyuncs.com", //ks3地址
		DisableSSL:       true,                       //是否禁用https
		LogLevel:         1,                          //是否开启日志,0为关闭日志,1为开启日志 n
		S3ForcePathStyle: false,                      //是否强制使用path style方式访问
		LogHTTPBody:      true,                       //是否把HTTP请求body打入日志
		Logger:           os.Stdout,                  //打日志的位置
	})

	// example for uploading file
	params := &s3.PutObjectInput{
		Bucket:      aws.String("BucketName"),              // bucket名称
		Key:         aws.String("ObjectKey"),               // object key
		ACL:         aws.String("public-read"),             //权限,支持private(私有),public-read(公开读)
		Body:        bytes.NewReader([]byte("PAYLOAD")),    //要上传的内容
		ContentType: aws.String("application/ocet-stream"), //设置content-type
		Metadata: map[string]*string{
			//"Key": aws.String("MetadataValue"), // 设置用户元数据
			// More values...
		},
	}
	resp, err := client.PutObject(params)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp)
	//获取新的文件名
	fmt.Println(*resp.NewFileName)

}

func assumeRoleRequest(ak string, sk string, region string) []byte { //调用ksc-go-sdk的sts服务
	svc := sts.SdkNew(ksc.NewClient(ak, sk /*,true*/), &ksc.Config{Region: &region}, &utils.UrlInfo{ //debug模式的话,打开true开关
		UseSSL:      true,
		UseInternal: false,
	})
	var resp *map[string]interface{}
	var err error

	//set your assumeRole here
	assumeRoleInput := make(map[string]interface{})
	assumeRoleInput["RoleKrn"] = "<YourRoleKrn>"
	assumeRoleInput["RoleSessionName"] = "Bob"
	assumeRoleInput["DurationSeconds"] = "3600"
	//assumeRole["Policy"] = ""

	resp, err = svc.AssumeRole(&assumeRoleInput)
	if err != nil {
		fmt.Println("error:", err.Error())
		return nil
	}
	var str []byte
	if resp != nil {
		str, _ = json.Marshal(&resp)
		//fmt.Printf("%+v\n", string(str))
	}
	return str
}

type (
	Response struct {
		AssumeRoleResult struct {
			Credentials struct {
				SecretAccessKey string `json:"SecretAccessKey"`
				Expiration      string `json:"Expiration"`
				AccessKeyId     string `json:"AccessKeyId"`
				SecurityToken   string `json:"SecurityToken"`
			} `json:"Credentials"`
			AssumedRoleUser struct {
				Krn           string `json:"Krn"`
				AssumedRoleId string `json:"AssumedRoleId"`
			} `json:"AssumedRoleUser"`
		} `json:AssumeRoleResult`
		RequestId string `json:"RequestId"`
	}
)

文档导读
纯净模式常规模式

纯净模式

点击可全屏预览文档内容
文档反馈