github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/docs/sts/web-identity.py (about)

     1  #!/usr/bin/env python
     2  # -*- coding: utf-8 -*-
     3  
     4  import json
     5  import logging
     6  import urllib
     7  from uuid import uuid4
     8  
     9  import boto3
    10  import requests
    11  from botocore.client import Config
    12  from flask import Flask, request
    13  
    14  boto3.set_stream_logger('boto3.resources', logging.DEBUG)
    15  
    16  authorize_url = "http://localhost:8080/auth/realms/minio/protocol/openid-connect/auth"
    17  token_url = "http://localhost:8080/auth/realms/minio/protocol/openid-connect/token"
    18  
    19  # callback url specified when the application was defined
    20  callback_uri = "http://localhost:8000/oauth2/callback"
    21  
    22  # keycloak id and secret
    23  client_id = 'account'
    24  client_secret = 'daaa3008-80f0-40f7-80d7-e15167531ff0'
    25  
    26  sts_client = boto3.client(
    27      'sts',
    28      region_name='us-east-1',
    29      use_ssl=False,
    30      endpoint_url='http://localhost:9000',
    31  )
    32  
    33  app = Flask(__name__)
    34  
    35  
    36  @app.route('/')
    37  def homepage():
    38      text = '<a href="%s">Authenticate with keycloak</a>'
    39      return text % make_authorization_url()
    40  
    41  
    42  def make_authorization_url():
    43      # Generate a random string for the state parameter
    44      # Save it for use later to prevent xsrf attacks
    45  
    46      state = str(uuid4())
    47      params = {"client_id": client_id,
    48                "response_type": "code",
    49                "state": state,
    50                "redirect_uri": callback_uri,
    51                "scope": "openid"}
    52  
    53      url = authorize_url + "?" + urllib.parse.urlencode(params)
    54      return url
    55  
    56  
    57  @app.route('/oauth2/callback')
    58  def callback():
    59      error = request.args.get('error', '')
    60      if error:
    61          return "Error: " + error
    62  
    63      authorization_code = request.args.get('code')
    64  
    65      data = {'grant_type': 'authorization_code',
    66              'code': authorization_code, 'redirect_uri': callback_uri}
    67      id_token_response = requests.post(
    68          token_url, data=data, verify=False,
    69          allow_redirects=False, auth=(client_id, client_secret))
    70  
    71      print('body: ' + id_token_response.text)
    72  
    73      # we can now use the id_token as much as we want to access protected resources.
    74      tokens = json.loads(id_token_response.text)
    75      id_token = tokens['id_token']
    76  
    77      response = sts_client.assume_role_with_web_identity(
    78          RoleArn='arn:aws:iam::123456789012:user/svc-internal-api',
    79          RoleSessionName='test',
    80          WebIdentityToken=id_token,
    81          DurationSeconds=3600
    82      )
    83  
    84      s3_resource = boto3.resource('s3',
    85                                   endpoint_url='http://localhost:9000',
    86                                   aws_access_key_id=response['Credentials']['AccessKeyId'],
    87                                   aws_secret_access_key=response['Credentials']['SecretAccessKey'],
    88                                   aws_session_token=response['Credentials']['SessionToken'],
    89                                   config=Config(signature_version='s3v4'),
    90                                   region_name='us-east-1')
    91  
    92      bucket = s3_resource.Bucket('testbucket')
    93  
    94      for obj in bucket.objects.all():
    95          print(obj)
    96  
    97      return "success"
    98  
    99  
   100  if __name__ == '__main__':
   101      app.run(debug=True, port=8000)