AssumeRoleResult not returning anything - java

I am trying to fetch temporary security credentials and use them to push/publish data on the Kinesis stream. Please check below code for obtaining credentials.
private AssumeRoleResult getAssumeRoleResult() {
AssumeRoleResult assumeRoleResult = null;
try {
log.info("Started to fetch AssumeRoleResult");
BasicSessionCredentials currentRoleCredentials = getCredentialsOfCurrentRole();
String sessionName = "assumedRole_" + RandomStringUtils.randomAlphanumeric(5).toUpperCase();
region = Config.getRegion();
AWSSecurityTokenService sts = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(currentRoleCredentials)).withRegion(region)
.build();
String roleArn = Configurations.ROLE_ARN;
assumeRoleResult = sts.assumeRole(new AssumeRoleRequest().withRoleArn(roleArn)
.withDurationSeconds(AWS_KINESIS_SESSION_DURATION)
.withRoleSessionName(sessionName));
log.info("Your AssumeRoleResult is" + assumeRoleResult.toString())
return assumeRoleResult;
} catch(Exception e) {
log.error("Failed to get AssumeRoleResult with error : {}", e.getMessage());
e.printStackTrace();
}
}
private BasicSessionCredentials getCredentialsOfCurrentRole() throws JSONException {
// Code to fetch IAM credentials for current role
}
But when I checked the logs, found that assumeRoleResult is not returning anything.(I am not seeing any log saying "Your AssumeRoleResult is" and also not exception found).
Can you please let me know what what may be issue here.

To fix this issue I added following changes
Updated Trust relationship for given account
https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/
Updated aws-java-sdk-kinesis and aws-java-sdk-sts to latest version.

Related

Are the Azure Workload Identity (Client Assertion) tokens compatible with the msal4j token cache?

I'm trying to use the Azure Workload Identity MSAL Java Sample, and I'm trying to figure out if the built-in token cache that comes with MSAL4J is actually usable with Azure Workload Identity (Client Assertions), as my understanding is that every time you request a new token, you need to read the AZURE_FEDERATED_TOKEN_FILE again (See // 1). I've looked through the MSAL4J code and to me it looks like you'd need to throw away the ConfidentialClientApplication (see // 2) and create a brand new one to load in a new federated token file, because the clientAssertion ends up baked into the client. So then I'd need to do my own checks to figure out if I need if I need to recreate the client, basically defeating the purpose of the built-in client.
Are my assumptions correct? Or is there some way to hook into the token refresh process and reload the clientAssertion?
Maybe MSAL4J needs integrated token cache support for Azure Workload Identity that handles the reloading of the client assertion on renewal?
Here is the sample code included for context.
public class CustomTokenCredential implements TokenCredential {
public Mono<AccessToken> getToken(TokenRequestContext request) {
Map<String, String> env = System.getenv();
String clientAssertion;
try {
clientAssertion = new String(Files.readAllBytes(Paths.get(env.get("AZURE_FEDERATED_TOKEN_FILE"))),
StandardCharsets.UTF_8); // 1
} catch (IOException e) {
throw new RuntimeException(e);
}
IClientCredential credential = ClientCredentialFactory.createFromClientAssertion(clientAssertion);
String authority = env.get("AZURE_AUTHORITY_HOST") + env.get("AZURE_TENANT_ID");
try {
ConfidentialClientApplication app = ConfidentialClientApplication
.builder(env.get("AZURE_CLIENT_ID"), credential).authority(authority).build(); // 2
Set<String> scopes = new HashSet<>();
for (String scope : request.getScopes())
scopes.add(scope);
ClientCredentialParameters parameters = ClientCredentialParameters.builder(scopes).build();
IAuthenticationResult result = app.acquireToken(parameters).join();
return Mono.just(
new AccessToken(result.accessToken(), result.expiresOnDate().toInstant().atOffset(ZoneOffset.UTC)));
} catch (Exception e) {
System.out.printf("Error creating client application: %s", e.getMessage());
System.exit(1);
}
return Mono.empty();
}
}

Amazon RDS Bad Request Exception

I am trying to query our database and map the results to a list of models. I am currently getting the following exception: Request type not supported: class com.amazon.rdsdataservice.ExecuteStatementRequest RequestID: Removed (Service: AWSRDSData; Status Code: 400; Error Code: BadRequestException; Request ID: Removed )
I wrote the rest of the code that queries the database and had no issues, this is the first instance where I am getting this exception.
Here is the method throwing the exception, it is occurring on the execute line.
public List<CompanyReportingTable> getCompanyReportingData(String monthsBack) {
List<CompanyReportingTable> reportingData = new ArrayList<>();
try {
Map<String, String> param = new LinkedHashMap<>();
param.put("monthsBack", monthsBack);
//Below is the line throwing the exception
reportingData = rdsDataClient.forSql(COMPANY_REPORTING_EXTRACTION_QUERY).withParameter(param).execute().mapToList(CompanyReportingTable.class);
} catch (Exception ex) {
LOGGER.error("Exception while querying company reporting data: " + ex.getMessage(), ex);
}
return reportingData;
}
I have made sure that the query is valid SQL and runs in the RDS query editor. I have been unable to find similar questions, any help would be appreciated.

Application is crashing when trying to create AmazonSNSClient

I am trying to create AmazonSNSClient and trying to list the platform application list as below.
AWSCredentials creds = new BasicAWSCredentials("XXXX", "XXXX");
try {
AmazonSNS snsClient = AmazonSNSClient
.builder()
.withRegion(Regions.US_EAST_2)
.withCredentials(new AWSStaticCredentialsProvider(creds))
.build();
ListPlatformApplicationsResult listResult = snsClient.listPlatformApplications(new ListPlatformApplicationsRequest());
Log.d(TAG, "ADM : Platform Applications : " + listResult.toString());
}
catch(Exception err) {
Log.d(TAG, "ADM : caught Exception while creating SNS client : " + err.toString());
}
I am able to create AWSCredentials and I am able to print the credentials I passed to BasicAWSCredentials. But Application is crashing when trying to create AmazonSNSClient and it is not even reaching catch block. I am using aws-java-sdk-1.11.646.jar. Can anyone please help me if there is anything wrong in the code or how to fix this issue.

Cognito SRP Authentication JAVA SDK

Iam trying to authenticate a Java app with Cognito.
I have used for python the warrant library that worked very good. But i want to do the same in java now.
My Python function i used for authentication with the warrant library
def SRPauthentication(organizationAdmin,
password,
pool_id,
client_id,
client):
aws = AWSSRP(username=organizationAdmin,
password=password,
pool_id=pool_id,
client_id=client_id,
client=client)
tokens = aws.authenticate_user()
authorization_token= tokens['AuthenticationResult']['IdToken']
return authorization_token
with this i could easily acces some secured APIs.
Now i want to do the same with Java but i have problems.
This is my solution so far is this method:
public static void GetCreds()
{
AWSCognitoIdentityProvider identityProvider = AWSCognitoIdentityProviderClientBuilder.defaultClient();
AdminInitiateAuthRequest adminInitiateAuthRequest = new AdminInitiateAuthRequest().
withAuthFlow(AuthFlowType.USER_SRP_AUTH).
withClientId("234234234234").withUserPoolId("eu-central-1_sdfsdfdsf")
.addAuthParametersEntry("USERNAME", "UserK").
addAuthParametersEntry("PASSWORD","#######);
adminInitiateAuthRequest.getAuthFlow();
AdminInitiateAuthResult adminInitiateAuth = identityProvider.adminInitiateAuth(adminInitiateAuthRequest);
System.out.println(adminInitiateAuth.getAuthenticationResult().getIdToken());
}
When i run this i get an Exception:
Exception in thread "main" `com.amazonaws.services.cognitoidp.model.AWSCognitoIdentityProviderException: User: arn:aws:iam::XXXXXXXXXXXXXXXXX:user/khan is not authorized to perform: cognito-idp:AdminInitiateAuth on resource: arn:aws:cognito-idp:eu-central-1:XXXXXXXX:userpool/eu-central-1_XXXXXXX with an explicit deny (Service: AWSCognitoIdentityProvider; Status Code: 400; Error Code: AccessDeniedException; Request ID: 21be0b8e-adec-11e8-ad45-234234234)`
It says iam not authorized to perform this kind of instruction. So i guess iam doing something generally wrong. Because its working with my python code and in Java it recognizes my username from the credentials. The Cognito call should actually be independent from my aws credentials/useraccount right?
How to authenticate with Cognito using Java to get an Token to access secured aws services?
EDIT:
AWSCognitoIdentityProvider identityProvider = AWSCognitoIdentityProviderClientBuilder.standard()
.build();
InitiateAuthRequest adminInitiateAuthRequest = new InitiateAuthRequest()
.withAuthFlow(AuthFlowType.USER_SRP_AUTH)
.withClientId("XXXXXXXXXXXXXXXXX")
.addAuthParametersEntry("USERNAME", "user").
addAuthParametersEntry("PASSWORD","za$Lwn")
.addAuthParametersEntry("SRP_A",new AuthenticationHelper("eu-central-1XXXXXXXXX").getA().toString(16));
adminInitiateAuthRequest.getAuthFlow();
InitiateAuthResult adminInitiateAuth = identityProvider.initiateAuth(adminInitiateAuthRequest);
System.out.println(adminInitiateAuth);
I changed the AdminInitateAuthRequest to InitateAuthRequest. After that i had the Error missing SRP_A parameter that i somehow fixed with a similiar question here
And now i recive this :
{ChallengeName: PASSWORD_VERIFIER,ChallengeParameters: {SALT=877734234324234ed68300f39bc5b, SECRET_BLOCK=lrkwejrlewrjlewkjrewlrkjwerlewkjrewlrkjewrlkewjrlewkrjZ+Q==, USER_ID_FOR_SRP=user, USERNAME=user, SRP_B=43ecc1lwkerjwelrkjewlrjewrlkewjrpoipweoriwe9r873jr34h9r834hr3455f7d079d71e5012f1623ed54dd10b832792dafa3438cca3f59c0f462cbaee255d5b7c2werwerwerkjweorkjwerwerewrf5020e4f8b5452f3b89caef4a797456743602b80b5259261f90e52374adc06b456521a9026cce9c1cbe8b9ffd6040e8c1589d35546861422110ac7e38c1c93389b802a03e3e2e4a50e75d088275195f836f66e25f1a431dd56bb2},}
I have shorten the result with all the keys, but what to do next ?
Finally i could solve it with this code class.
There are multiple challenges involved in SRP authentication. The InitiateAuthRequest is one first request that is necessary.
This similiar question helped me :
stackoverflow
stackoverfow
String PerformSRPAuthentication(String username, String password) {
String authresult = null;
InitiateAuthRequest initiateAuthRequest = initiateUserSrpAuthRequest(username);
try {
AnonymousAWSCredentials awsCreds = new AnonymousAWSCredentials();
AWSCognitoIdentityProvider cognitoIdentityProvider = AWSCognitoIdentityProviderClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.withRegion(Regions.fromName(this.region))
.build();
InitiateAuthResult initiateAuthResult = cognitoIdentityProvider.initiateAuth(initiateAuthRequest);
if (ChallengeNameType.PASSWORD_VERIFIER.toString().equals(initiateAuthResult.getChallengeName())) {
RespondToAuthChallengeRequest challengeRequest = userSrpAuthRequest(initiateAuthResult, password);
RespondToAuthChallengeResult result = cognitoIdentityProvider.respondToAuthChallenge(challengeRequest);
//System.out.println(result);
System.out.println(CognitoJWTParser.getPayload(result.getAuthenticationResult().getIdToken()));
authresult = result.getAuthenticationResult().getIdToken();
}
} catch (final Exception ex) {
System.out.println("Exception" + ex);
}
return authresult;
}
private InitiateAuthRequest initiateUserSrpAuthRequest(String username) {
InitiateAuthRequest initiateAuthRequest = new InitiateAuthRequest();
initiateAuthRequest.setAuthFlow(AuthFlowType.USER_SRP_AUTH);
initiateAuthRequest.setClientId(this.clientId);
//Only to be used if the pool contains the secret key.
//initiateAuthRequest.addAuthParametersEntry("SECRET_HASH", this.calculateSecretHash(this.clientId,this.secretKey,username));
initiateAuthRequest.addAuthParametersEntry("USERNAME", username);
initiateAuthRequest.addAuthParametersEntry("SRP_A", this.getA().toString(16));
return initiateAuthRequest;
}

How to get status of mail send by Mandrill java api?

I have get an Internal server exception for getting mail information while using lutung's java API of mandrill. Here is my code.
public MandrillMessageInfo getMessageInfo(String id) {
MandrillApi mandrillApi = new MandrillApi("Your api key");
MandrillMessageInfo info = null;
try {
info = mandrillApi.messages().info(id);
log.debug("Message status-> Email {}, state: {}, timeOfSent: {} ", info.getEmail() ,info.getState(), TimeUtil.getLocalTimeString(info.getTs()));
} catch (Exception e) {
log.debug("Exception occurs while getting message info for id: {}, exception is: {} ", id, e.getMessage());
throw new MailServiceException(ErrorCodes.ERROR_INTERNAL_SERVER_ERROR, ErrorCodes.ERROR_MESSAGE_INTERNAL_SERVER_ERROR);
}
return info;
}
I see nothing wrong in your code. If your API key is right, the only reason this request will return an error is if you give a wrong id. You can verify that by issuing a messages/info api request directly on mandrill website using "Try It" button https://mandrillapp.com/api/docs/messages.JSON.html#method=info and pass the same message id, that you are giving via the program call.
Hope this helps,

Categories