Recently we were trying to authenticate using username and password of the user using a AWS Cognito client which was configured with a secret. We got the following error:
Client <client ID> is configured for secret but secret was not received (Service: AWSCognitoIdentityProvider; Status Code: 400; Error Code: NotAuthorizedException; Request ID: e42de11b-380b-4935-b97e-1069ab925a35; Proxy: null)
We tried may ways for passing Cognito client secret to authenticate API but nothing worked. After trying a lot and searching internet I came to the following page which tells about calculating secret hash.
Following is the code for calculating secret hash. This code is taken from above link.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public static String calculateSecretHash(String userPoolClientId, String userPoolClientSecret, String userName) {
final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
SecretKeySpec signingKey = new SecretKeySpec(
userPoolClientSecret.getBytes(StandardCharsets.UTF_8),
HMAC_SHA256_ALGORITHM);
try {
Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
mac.init(signingKey);
mac.update(userName.getBytes(StandardCharsets.UTF_8));
byte[] rawHmac = mac.doFinal(userPoolClientId.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(rawHmac);
} catch (Exception e) {
throw new RuntimeException("Error while calculating ");
}
}
The secret hash calculated hash needs to passed to authentication API along with username and password.
Map<String, String> authParams = new LinkedHashMap<>() {{
put("USERNAME", username);
put("PASSWORD", password);
put("SECRET_HASH", secret_hash);
}};
Using this method we were able to finally generate authentication token for Cognito client for which client secret is configured.
No comments:
Post a Comment