8
2

More than 3 years have passed since last update.

boto3 を用いて MinIO でユーザの追加と Security Token Service(STS) による一時認証情報での署名済み URL を発行する

Posted at

ある環境で AWS S3 の署名済み URL を用いて感動しました。
そこで,MinIO on Docker でマルチユーザ&署名済み URL によるアップロードやアクセスに対応し,手元の環境でも感動を味わえるようにします。

前提条件

MinIO クライアント

インストール

MinIO | MinIO Client Quickstart Guide を参考にクライアントツールをインストールし,mc コマンドを使えるようにします。

docker を用いる場合は docker pull minio/mc で macOS の方で Homebrew を導入済みの方は brew install minio/stable/mc でコマンドで MinIO クライアントを導入できます。

docker を用いる際は,以降の mc コマンドを用いるところは docker run -it --entrypoint=/bin/sh minio/mc で環境を立ち上げてからコマンドを入力してください。

セットアップ

サーバへの接続情報を設定します:

$ # mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY>
$ mc config host add minio http://127.0.0.1:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

実際に動作確認としてすでにあるバケットの一覧を取得します:

$ # mc ls <ALIAS>
$ mc ls minio

ユーザ作成

全権アカウントとは別にバケット毎の作業用アカウントを作成します。
まずはバケットを作成します:

$ mc mb minio/my-bucketname

作成した my-bucketname バケットに対して操作可能なアカウントを作成しましょう。

ポリシーの作成

新しく作成するアカウントに適応するポリシーを事前に追加します。
ポリシーは json で設定ファイルを作成し,mc コマンドで実際にサーバに登録します。

my-bucketname.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::my-bucketname/*"
      ],
      "Sid": ""
    }
  ]
}

設定ファイルを作成したら,実際にサーバにポリシーを追加しましょう:

$ mc admin policy add minio my-bucketname my-bucketname.json

Added policy `my-bucketname` successfully. と表示されれば成功です。

ユーザの作成

新しくユーザを作成し,上で作成したポリシーを適用します。

$ mc admin user add minio newuser newuser123  # 新しくユーザを作成
$ mc admin policy set minio my-bucketname user=newuser  # 作成したユーザにポリシーを設定

Security Token Service(STS) による一時アカウントの発行と STS を用いた署名済み URL の発行

前準備

まずは Web 画面から事前に my-bucketname バケットにファイルを保存します。
今回は test.txt という名前で保存したものとして,以降進めます。

ソースコード

今回は AWS の SDK である boto3 を用います。

$ pip install boto3  # boto3 をインストール

実際にプログラムを作成して署名済み URL を取得・表示します。
下のプログラムでは,MinIO への認証情報も直接書いていますが,実際に利用する際は profile を作成したり,環境変数で設定しましょう。

import json

import boto3
from boto3.session import Session
from botocore.config import Config

endpoint = 'http://127.0.0.1:9000'  # MinIO サーバの URL

my_config = Config(
    signature_version = 'v4',
)
# 一時アカウントに設定するポリシーを定義
policy = {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::my-bucketname/*"
      ],
      "Sid": "Stmt1"
    }
  ]

}

# boto3 を事前に作成したアカウントでクライアントを用意
client = boto3.client('sts',
                      aws_access_key_id='YOUR_ACCESS_KEY',  # アクセスキーを設定する
                      aws_secret_access_key='YOUR_SECRET_KEY',  # シークレットキーを設定する
                      config=my_config, endpoint_url=endpoint)

# 一時アカウントの取得
response = client.assume_role(
    RoleArn='arn:xxx:xxx:xxx:xxxx',  # AWS との互換のために適当に値を入れる
    RoleSessionName='anything',  # 同上
    Policy=json.dumps(policy, separators=(',',':')),  # ポリシーは JSON の文字列で渡す ※空白は付与しない
    # 一時アカウントの有効期間 (900秒から43200秒の範囲で設定する
    DurationSeconds=900,
)

# 上で取得した一時アカウントのうち,署名済み URL 発行に必要な分を取り出す
sts = {
    'aws_access_key_id': response['Credentials']['AccessKeyId'],
    'aws_secret_access_key': response['Credentials']['SecretAccessKey'],
    'aws_session_token': response['Credentials']['SessionToken']   
}

# 一時アカウントで接続する準備
session = Session(**sts)

# 一時アカウントでクライアントを用意
s3 = session.client('s3', config=Config(signature_version='s3v4'), endpoint_url=endpoint)

# 署名済み URL を取得 ()
url = s3.generate_presigned_url(
    ClientMethod='get_object',  # 許可するAPIメソッド(今回は get_object: ファイルの取得)
    Params={'Bucket': 'my-bucketname', 'Key': 'test.txt'},  # ファイル情報
    ExpiresIn=60,  # URL の有効期間 (デフォルトは 3600秒)
    HttpMethod='GET')  # 許可する HTTP メソッド(今回は GET)

print(url)  # 署名済み URL を出力

出力された URL にアクセスすると事前にアップロードしておいた test.txt ファイルの中身が確認できると思います。

参考

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2