javaamazon-s3minioaws-s3-clients3-iam-policy

How to setup user policy for the minio bucket using s3Client?


We use Minio as our backend service but we communicate with it through

software.amazon.awssdk.services.s3.S3Client

I see that this class contains method putBucketPolicy

but I don't see any method which allow to assign policy to user. Is there any way to assigh user policy using S3Client ?


Solution

  • Edited Answer:

    Your updated question helped me determine what you were looking for.

    You need to create a policy and assign it to a role. You can then assign that role to your user. The AWS SDK for Java 2.x provides support for all of these actions with IAM.

    Here's what we can do:

    1- Creating a policy

    To create a new policy, provide the policy’s name and a JSON-formatted policy document in a CreatePolicyRequest to the IamClient’s createPolicy method.

    Imports

    import software.amazon.awssdk.core.waiters.WaiterResponse;
    import software.amazon.awssdk.services.iam.model.CreatePolicyRequest;
    import software.amazon.awssdk.services.iam.model.CreatePolicyResponse;
    import software.amazon.awssdk.services.iam.model.GetPolicyRequest;
    import software.amazon.awssdk.services.iam.model.GetPolicyResponse;
    import software.amazon.awssdk.services.iam.model.IamException;
    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.iam.IamClient;
    import software.amazon.awssdk.services.iam.waiters.IamWaiter;
    

    Code

        public static String createIAMPolicy(IamClient iam, String policyName ) {
    
            try {
                // Create an IamWaiter object
                IamWaiter iamWaiter = iam.waiter();
    
                CreatePolicyRequest request = CreatePolicyRequest.builder()
                    .policyName(policyName)
                    .policyDocument(PolicyDocument).build();
    
                CreatePolicyResponse response = iam.createPolicy(request);
    
                // Wait until the policy is created
                GetPolicyRequest polRequest = GetPolicyRequest.builder()
                        .policyArn(response.policy().arn())
                        .build();
    
                WaiterResponse<GetPolicyResponse> waitUntilPolicyExists = iamWaiter.waitUntilPolicyExists(polRequest);
                waitUntilPolicyExists.matched().response().ifPresent(System.out::println);
                return response.policy().arn();
    
             } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
            return "" ;
        }
    

    You can check out CreatePolicy.java for complete example.

    2- Attach a role policy

    You can attach a policy to an IAM role by calling the IamClient’s attachRolePolicy method.

    Imports

    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.iam.IamClient;
    import software.amazon.awssdk.services.iam.model.IamException;
    import software.amazon.awssdk.services.iam.model.AttachRolePolicyRequest;
    import software.amazon.awssdk.services.iam.model.AttachedPolicy;
    import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesRequest;
    import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesResponse;
    import java.util.List;
    

    Code

        public static void attachIAMRolePolicy(IamClient iam, String roleName, String policyArn ) {
    
            try {
    
                 ListAttachedRolePoliciesRequest request = ListAttachedRolePoliciesRequest.builder()
                        .roleName(roleName)
                        .build();
    
                ListAttachedRolePoliciesResponse  response = iam.listAttachedRolePolicies(request);
                List<AttachedPolicy> attachedPolicies = response.attachedPolicies();
    
                // Ensure that the policy is not attached to this role
                String polArn = "";
                for (AttachedPolicy policy: attachedPolicies) {
                    polArn = policy.policyArn();
                    if (polArn.compareTo(policyArn)==0) {
                       System.out.println(roleName +
                                " policy is already attached to this role.");
                        return;
                    }
              }
    
                AttachRolePolicyRequest attachRequest =
                    AttachRolePolicyRequest.builder()
                            .roleName(roleName)
                            .policyArn(policyArn)
                            .build();
    
                iam.attachRolePolicy(attachRequest);
    
                System.out.println("Successfully attached policy " + policyArn +
                    " to role " + roleName);
    
             } catch (IamException e) {
                    System.err.println(e.awsErrorDetails().errorMessage());
                    System.exit(1);
              }
    
         System.out.println("Done");
        }
    

    You can check out AttachRolePolicy.java for complete example.

    Bonus Content

    Scenario for create a user and assume a role

    The following code example shows how to:

    /*
      To run this Java V2 code example, set up your development environment, including your credentials.
    
      For information, see this documentation topic:
    
      https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
    
      This example performs these operations:
    
      1. Creates a user that has no permissions.
      2. Creates a role and policy that grants Amazon S3 permissions.
      3. Creates a role.
      4. Grants the user permissions.
      5. Gets temporary credentials by assuming the role.  Creates an Amazon S3 Service client object with the temporary credentials.
      6. Deletes the resources.
     */
    
    public class IAMScenario {
        public static final String DASHES = new String(new char[80]).replace("\0", "-");
        public static final String PolicyDocument =
                "{" +
                        "  \"Version\": \"2012-10-17\"," +
                        "  \"Statement\": [" +
                        "    {" +
                        "        \"Effect\": \"Allow\"," +
                        "        \"Action\": [" +
                        "            \"s3:*\"" +
                        "       ]," +
                        "       \"Resource\": \"*\"" +
                        "    }" +
                        "   ]" +
                        "}";
    
        public static void main(String[] args) throws Exception {
    
            final String usage = "\n" +
                "Usage:\n" +
                "    <username> <policyName> <roleName> <roleSessionName> <fileLocation> <bucketName> \n\n" +
                "Where:\n" +
                "    username - The name of the IAM user to create. \n\n" +
                "    policyName - The name of the policy to create. \n\n" +
                "    roleName - The name of the role to create. \n\n" +
                "    roleSessionName - The name of the session required for the assumeRole operation. \n\n" +
                "    fileLocation - The file location to the JSON required to create the role (see Readme). \n\n" +
                "    bucketName - The name of the Amazon S3 bucket from which objects are read. \n\n" ;
    
            if (args.length != 6) {
                System.out.println(usage);
                System.exit(1);
            }
    
            String userName = args[0];
            String policyName = args[1];
            String roleName = args[2];
            String roleSessionName = args[3];
            String fileLocation = args[4];
            String bucketName = args[5];
    
            Region region = Region.AWS_GLOBAL;
            IamClient iam = IamClient.builder()
                .region(region)
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();
    
            System.out.println(DASHES);
            System.out.println("Welcome to the AWS IAM example scenario.");
            System.out.println(DASHES);
    
            System.out.println(DASHES);
            System.out.println(" 1. Create the IAM user.");
            Boolean createUser = createIAMUser(iam, userName);
            System.out.println(DASHES);
    
           if (createUser) {
               System.out.println(userName + " was successfully created.");
    
               System.out.println(DASHES);
               System.out.println("2. Creates a policy.");
               String polArn = createIAMPolicy(iam, policyName);
               System.out.println("The policy " + polArn + " was successfully created.");
               System.out.println(DASHES);
    
               System.out.println(DASHES);
               System.out.println("3. Creates a role.");
               String roleArn = createIAMRole(iam, roleName, fileLocation);
               System.out.println(roleArn + " was successfully created.");
               System.out.println(DASHES);
    
               System.out.println(DASHES);
               System.out.println("4. Grants the user permissions.");
               attachIAMRolePolicy(iam, roleName, polArn);
               System.out.println(DASHES);
    
               System.out.println(DASHES);
               System.out.println("*** Wait for 1 MIN so the resource is available");
               TimeUnit.MINUTES.sleep(1);
               System.out.println("5. Gets temporary credentials by assuming the role.");
               System.out.println("Perform an Amazon S3 Service operation using the temporary credentials.");
               assumeGivenRole(roleArn, roleSessionName, bucketName);
               System.out.println(DASHES);
    
               System.out.println(DASHES);
               System.out.println("6 Getting ready to delete the AWS resources");
               deleteRole(iam, roleName, polArn);
               deleteIAMUser(iam, userName);
               System.out.println(DASHES);
    
               System.out.println(DASHES);
               System.out.println("This IAM Scenario has successfully completed");
               System.out.println(DASHES);
           } else {
               System.out.println(userName +" was not successfully created.");
           }
        }
    
        public static Boolean createIAMUser(IamClient iam, String username ) {
    
            try {
                // Create an IamWaiter object
                IamWaiter iamWaiter = iam.waiter();
                CreateUserRequest request = CreateUserRequest.builder()
                    .userName(username)
                    .build();
    
                // Wait until the user is created.
                CreateUserResponse response = iam.createUser(request);
                GetUserRequest userRequest = GetUserRequest.builder()
                    .userName(response.user().userName())
                    .build();
    
                WaiterResponse<GetUserResponse> waitUntilUserExists = iamWaiter.waitUntilUserExists(userRequest);
                waitUntilUserExists.matched().response().ifPresent(System.out::println);
                return true;
    
            } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
            return false;
        }
    
        public static String createIAMRole(IamClient iam, String rolename, String fileLocation ) throws Exception {
    
            try {
                JSONObject jsonObject = (JSONObject) readJsonSimpleDemo(fileLocation);
                CreateRoleRequest request = CreateRoleRequest.builder()
                    .roleName(rolename)
                    .assumeRolePolicyDocument(jsonObject.toJSONString())
                    .description("Created using the AWS SDK for Java")
                    .build();
    
                CreateRoleResponse response = iam.createRole(request);
                System.out.println("The ARN of the role is "+response.role().arn());
                return response.role().arn();
    
            } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
            return "";
        }
    
        public static String createIAMPolicy(IamClient iam, String policyName ) {
    
            try {
                // Create an IamWaiter object.
                IamWaiter iamWaiter = iam.waiter();
                CreatePolicyRequest request = CreatePolicyRequest.builder()
                    .policyName(policyName)
                    .policyDocument(PolicyDocument).build();
    
                CreatePolicyResponse response = iam.createPolicy(request);
    
                // Wait until the policy is created.
                GetPolicyRequest polRequest = GetPolicyRequest.builder()
                    .policyArn(response.policy().arn())
                    .build();
    
                WaiterResponse<GetPolicyResponse> waitUntilPolicyExists = iamWaiter.waitUntilPolicyExists(polRequest);
                waitUntilPolicyExists.matched().response().ifPresent(System.out::println);
                return response.policy().arn();
    
            } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
            return "" ;
        }
    
        public static void attachIAMRolePolicy(IamClient iam, String roleName, String policyArn ) {
    
            try {
                ListAttachedRolePoliciesRequest request = ListAttachedRolePoliciesRequest.builder()
                    .roleName(roleName)
                    .build();
    
                ListAttachedRolePoliciesResponse response = iam.listAttachedRolePolicies(request);
                List<AttachedPolicy> attachedPolicies = response.attachedPolicies();
    
                String polArn;
                for (AttachedPolicy policy: attachedPolicies) {
                    polArn = policy.policyArn();
                    if (polArn.compareTo(policyArn)==0) {
                        System.out.println(roleName + " policy is already attached to this role.");
                        return;
                    }
                }
    
                AttachRolePolicyRequest attachRequest = AttachRolePolicyRequest.builder()
                    .roleName(roleName)
                    .policyArn(policyArn)
                    .build();
    
                iam.attachRolePolicy(attachRequest);
                System.out.println("Successfully attached policy " + policyArn + " to role " + roleName);
    
            } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
        }
    
        // Invoke an Amazon S3 operation using the Assumed Role.
        public static void assumeGivenRole(String roleArn, String roleSessionName, String bucketName) {
    
            StsClient stsClient = StsClient.builder()
                .region(Region.US_EAST_1)
                .build();
    
            try {
                AssumeRoleRequest roleRequest = AssumeRoleRequest.builder()
                    .roleArn(roleArn)
                    .roleSessionName(roleSessionName)
                    .build();
    
                AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest);
                Credentials myCreds = roleResponse.credentials();
                String key = myCreds.accessKeyId();
                String secKey = myCreds.secretAccessKey();
                String secToken = myCreds.sessionToken();
    
                // List all objects in an Amazon S3 bucket using the temp creds.
                Region region = Region.US_EAST_1;
                S3Client s3 = S3Client.builder()
                    .credentialsProvider(StaticCredentialsProvider.create(AwsSessionCredentials.create(key, secKey, secToken)))
                    .region(region)
                    .build();
    
                System.out.println("Created a S3Client using temp credentials.");
                System.out.println("Listing objects in "+bucketName);
                ListObjectsRequest listObjects = ListObjectsRequest.builder()
                    .bucket(bucketName)
                    .build();
    
                ListObjectsResponse res = s3.listObjects(listObjects);
                List<S3Object> objects = res.contents();
                for (S3Object myValue : objects) {
                    System.out.println("The name of the key is " + myValue.key());
                    System.out.println("The owner is " + myValue.owner());
                }
    
            } catch (StsException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }
        }
    
        public static void deleteRole(IamClient iam, String roleName, String polArn) {
    
            try {
                // First the policy needs to be detached.
                DetachRolePolicyRequest rolePolicyRequest = DetachRolePolicyRequest.builder()
                    .policyArn(polArn)
                    .roleName(roleName)
                    .build();
    
                iam.detachRolePolicy(rolePolicyRequest);
    
                // Delete the policy.
                DeletePolicyRequest request = DeletePolicyRequest.builder()
                    .policyArn(polArn)
                    .build();
    
                iam.deletePolicy(request);
                System.out.println("*** Successfully deleted "+polArn);
    
                // Delete the role.
                DeleteRoleRequest roleRequest = DeleteRoleRequest.builder()
                    .roleName(roleName)
                    .build();
    
                iam.deleteRole(roleRequest);
                System.out.println("*** Successfully deleted " +roleName);
    
            } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
        }
    
        public static void deleteIAMUser(IamClient iam, String userName) {
    
            try {
                DeleteUserRequest request = DeleteUserRequest.builder()
                    .userName(userName)
                    .build();
    
                iam.deleteUser(request);
                System.out.println("*** Successfully deleted " + userName);
    
            } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
        }
    
        public static Object readJsonSimpleDemo(String filename) throws Exception {
            FileReader reader = new FileReader(filename);
            JSONParser jsonParser = new JSONParser();
            return jsonParser.parse(reader);
        }
    }
    
    


    Original Answer:

    PutBucketPolicy

    If you don't have PutBucketPolicy permissions, Amazon S3 returns a 403 Access Denied error. If you have the correct permissions, but you're not using an identity that belongs to the bucket owner's account, Amazon S3 returns a 405 Method Not Allowed error.

    You can check out for more from AWS API Reference: PutBucketPolicy