Application is crashing when trying to create AmazonSNSClient - java

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.

Related

GoogleCredentials: getTokenValue() works on emulator, but not on an actual device

For use on a mobile app, I'm authenticating for a Firebase realtime db. The code for reading the private key and generating an access token works fine on the Android emulator, but generates an error on an actual phone.
Here's the code:
private String getToken () {
try {
InputStream serviceAccount = getApplicationContext().getAssets().open("asset.json");
GoogleCredentials googleCred = GoogleCredentials
.fromStream (serviceAccount)
.createScoped (Arrays.asList(
"https://www.googleapis.com/auth/firebase.database",
"https://www.googleapis.com/auth/userinfo.email"
));
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
return googleCred.refreshAccessToken().getTokenValue();
}
catch (Exception e) {
Log.d ("getToken", "Auth 2 Error: " + e);
return "";
}
}
catch (Exception e) {
Log.d ("getToken", "Auth 1 Error: " + e);
return "";
}
}
When this code is run on the phone, the error generated is:
Auth 2 Error:
I5.m: Error getting access token for service account: 400 Bad Request
POST https://oauth2.googleapis.com/token
{
"error": "invalid_grant",
"error_description": "Invalid grant: account not found"
}
iss: xxxredactedxxx#appspot.gserviceaccount.com
The private key asset is being read correctly on both emulator and phone, so I suspect the problem is not in the code, but something in my Firebase and/or Google Cloud setup. What "account" is needed when the app is run on a phone but not in the emulator? And where would I set up that account?
Edit: In the Google Cloud Service Accounts page, I've added the iss account (in the error message) to "Principals with access to this Service Account" table:
Principal: xxxredactedxxx#appspot.gserviceaccount.com
Name: App Engine default service account
Role: Editor
Service Account Token Creator
(To be clear, I'm not using logins or other userid/password-style authentication; the app should connect internally to its db in Firebase in a read-only mode, based on the private key).

Connect to elasticfilesystem.ap-south-1.amazonaws.com:80 failed: Connection refused From Java SDK

I try to connect Aws EFS using Java Aws sdk. But its Giving Me Error.*
Unable to execute HTTP request: Connect to
elasticfilesystem.ap-south-1.amazonaws.com:80
[elasticfilesystem.ap-south-1.amazonaws.com/52.95.85.30] failed:
Connection refused
I do not find any example about pragmatically perform operation with Efs. Has there any code example and reference?
I try to do something but i am confused i am on right or wrong track. Here i provide my code:
AWSCredentials credentials = new BasicAWSCredentials (
"*******************",
"****************************");
ClientConfiguration clientConfig = new ClientConfiguration ();
clientConfig.setProtocol (Protocol.HTTP);
clientConfig.setMaxErrorRetry (DEFAULT_MAX_ERROR_RETRY);
clientConfig.setRetryPolicy (new RetryPolicy (PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION,
DEFAULT_BACKOFF_STRATEGY, DEFAULT_MAX_ERROR_RETRY, false));
AmazonElasticFileSystem fileSystem = AmazonElasticFileSystemClientBuilder.standard ()
.withClientConfiguration (clientConfig)
.withCredentials (new AWSStaticCredentialsProvider (credentials))
.build ();
CreateFileSystemResult result = fileSystem.createFileSystem (new CreateFileSystemRequest ());
System.out.println (result);
Aws expecting HTTPS protocol and Add region of Builder:
AWScredentials credentials = new BasicAWSCredentials (
"*******************",
"****************************");
ClientConfiguration clientConfig = new ClientConfiguration ();
clientConfig.setProtocol (Protocol.HTTPS); // make it HTTPS
clientConfig.setMaxErrorRetry (DEFAULT_MAX_ERROR_RETRY);
clientConfig.setRetryPolicy (new RetryPolicy (PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION,
DEFAULT_BACKOFF_STRATEGY, DEFAULT_MAX_ERROR_RETRY, false));
AmazonElasticFileSystem fileSystem = AmazonElasticFileSystemClientBuilder.standard ()
.withClientConfiguration (clientConfig)
.withRegion ("ap-south-1") // add region
.withCredentials (new AWSStaticCredentialsProvider (credentials))
.build ();
CreateFileSystemResult result = fileSystem.createFileSystem (new CreateFileSystemRequest ());
System.out.println (result);
It's working for me. I hope it will help others.

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();
}
}

AssumeRoleResult not returning anything

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.

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;
}

Categories