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 ?
CodePudding user response:
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:
- Create a user who has no permissions.
- Create a role that grants permission to list Amazon S3 buckets for the account.
- Add a policy to let the user assume the role.
- Assume the role and list Amazon S3 buckets using temporary credentials.
- Delete the policy, role, and user.
/*
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