Skip to content

Commit

Permalink
Fix #1636: For API /auth/combinded assert credentialName (#1637)
Browse files Browse the repository at this point in the history
* Fix #1636: For API /auth/combinded assert credentialName
 - remove credentialName completely from combined auth
- add migration docs
- update API ref
- remove param from java doc
  • Loading branch information
jandusil authored May 6, 2024
1 parent 12f7fa0 commit df72894
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 30 deletions.
1 change: 1 addition & 0 deletions docs/Migration-Instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

This page contains PowerAuth Web Flow migration instructions.

- [PowerAuth Web Flow 1.8.0](./Web-Flow-1.8.0.md)
- [PowerAuth Web Flow 1.7.0](./Web-Flow-1.7.0.md)
- [PowerAuth Web Flow 1.6.0](./Web-Flow-1.6.0.md)
- [PowerAuth Web Flow 1.5.0](./Web-Flow-1.5.0.md)
Expand Down
1 change: 0 additions & 1 deletion docs/Next-Step-Server-REST-API-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -8823,7 +8823,6 @@ The list of expected status codes:
```json
{
"requestObject": {
"credentialName": "RETAIL_CREDENTIAL",
"userId": "test1234",
"credentialValue": ")wOI6ijUkwYI",
"authenticationMode": "MATCH_EXACT",
Expand Down
10 changes: 10 additions & 0 deletions docs/Web-Flow-1.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Migration from 1.7.0 to 1.8.0

This guide contains instructions for migration from PowerAuth WebFlow version `1.7.x` to version `1.8.0`.

## API

### Attribute `credentialName` modification

The attribute `credentialName` has been removed from the request object of the API endpoint `/auth/combined`. This change
was made because the attribute was not utilized in the underlying functionality.
Original file line number Diff line number Diff line change
Expand Up @@ -2416,18 +2416,16 @@ public ObjectResponse<CredentialAuthenticationResponse> authenticateWithCredenti
/**
* Authenticate using credential and OTP without operation.
*
* @param credentialName Credential name.
* @param userId User ID.
* @param credentialValue Credential value.
* @param otpId OTP ID.
* @param otpValue OTP value.
* @return OTP authentication response.
* @throws NextStepClientException Thrown when REST API call fails, including {@link ErrorResponse} with error code.
*/
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String credentialName, @NotNull String userId, @NotNull String credentialValue,
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String userId, @NotNull String credentialValue,
String otpId, @NotNull String otpValue) throws NextStepClientException {
final CombinedAuthenticationRequest request = new CombinedAuthenticationRequest();
request.setCredentialName(credentialName);
request.setUserId(userId);
request.setCredentialValue(credentialValue);
request.setOtpId(otpId);
Expand All @@ -2438,7 +2436,6 @@ public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotN
/**
* Authenticate using credential and OTP without operation and with additional details.
*
* @param credentialName Credential name.
* @param userId User ID.
* @param credentialValue Credential value.
* @param authenticationMode Authentication mode.
Expand All @@ -2448,11 +2445,10 @@ public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotN
* @return OTP authentication response.
* @throws NextStepClientException Thrown when REST API call fails, including {@link ErrorResponse} with error code.
*/
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String credentialName, @NotNull String userId, @NotNull String credentialValue,
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String userId, @NotNull String credentialValue,
CredentialAuthenticationMode authenticationMode, List<Integer> credentialPositionsToVerify,
String otpId, @NotNull String otpValue) throws NextStepClientException {
final CombinedAuthenticationRequest request = new CombinedAuthenticationRequest();
request.setCredentialName(credentialName);
request.setUserId(userId);
request.setCredentialValue(credentialValue);
request.setAuthenticationMode(authenticationMode);
Expand All @@ -2465,7 +2461,6 @@ public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotN
/**
* Authenticate using credential and OTP with operation.
*
* @param credentialName Credential name.
* @param userId User ID.
* @param credentialValue Credential value.
* @param otpId OTP ID.
Expand All @@ -2476,11 +2471,10 @@ public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotN
* @return OTP authentication response.
* @throws NextStepClientException Thrown when REST API call fails, including {@link ErrorResponse} with error code.
*/
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String credentialName, @NotNull String userId, @NotNull String credentialValue,
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String userId, @NotNull String credentialValue,
String otpId, String operationId, @NotNull String otpValue,
boolean updateOperation, AuthMethod authMethod) throws NextStepClientException {
final CombinedAuthenticationRequest request = new CombinedAuthenticationRequest();
request.setCredentialName(credentialName);
request.setUserId(userId);
request.setCredentialValue(credentialValue);
request.setOtpId(otpId);
Expand All @@ -2494,7 +2488,6 @@ public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotN
/**
* Authenticate using credential and OTP with operation and with additional details.
*
* @param credentialName Credential name.
* @param userId User ID.
* @param credentialValue Credential value.
* @param authenticationMode Authentication mode.
Expand All @@ -2507,12 +2500,11 @@ public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotN
* @return OTP authentication response.
* @throws NextStepClientException Thrown when REST API call fails, including {@link ErrorResponse} with error code.
*/
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String credentialName, @NotNull String userId, @NotNull String credentialValue,
public ObjectResponse<CombinedAuthenticationResponse> authenticateCombined(@NotNull String userId, @NotNull String credentialValue,
CredentialAuthenticationMode authenticationMode, List<Integer> credentialPositionsToVerify,
String otpId, String operationId, @NotNull String otpValue,
boolean updateOperation, AuthMethod authMethod) throws NextStepClientException {
final CombinedAuthenticationRequest request = new CombinedAuthenticationRequest();
request.setCredentialName(credentialName);
request.setUserId(userId);
request.setCredentialValue(credentialValue);
request.setAuthenticationMode(authenticationMode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
@Data
public class CombinedAuthenticationRequest {

@NotBlank
@Size(min = 2, max = 256)
private String credentialName;
@NotBlank
@Size(min = 1, max = 256)
private String userId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,9 @@ public CombinedAuthenticationResponse authenticateCombined(CombinedAuthenticatio
final IdGeneratorService idGeneratorService = serviceCatalogue.getIdGeneratorService();

final OtpEntity otp = otpService.findOtp(request.getOtpId(), request.getOperationId());
if (otp.getCredentialDefinition() == null || otp.getCredentialDefinition().getName() == null) {
throw new InvalidRequestException("Credential definition is not set for operation with OTP Id and Operation Id: " + request.getOtpId() + ", " + request.getOperationId());
}
if (otp.getOtpDefinition().isDataAdapterProxyEnabled()) {
logger.info("Combined authentication proxied through Data Adapter, OTP ID: {}", request.getOtpId());
return authenticateCombinedCustom(otp.getCredentialDefinition(), otp.getOtpId(), request.getOtpValue(), request.getCredentialValue(), otp.getOperation().getOperationId(), otp.getUserId(), request.getAuthMethod());
Expand All @@ -577,10 +580,10 @@ public CombinedAuthenticationResponse authenticateCombined(CombinedAuthenticatio
operation = operationPersistenceService.getOperation(request.getOperationId());
}
if (request.isUpdateOperation() && operation == null) {
throw new InvalidRequestException("Operation not found, however operation update requested for credential and OTP: " + request.getCredentialName() + ", " + otp.getOtpDefinition().getName());
throw new InvalidRequestException("Operation not found, however operation update requested for credential and OTP: " + otp.getCredentialDefinition().getName() + ", " + otp.getOtpDefinition().getName());
}
if (request.getOperationId() != null && !request.getOperationId().equals(otp.getOperation().getOperationId())) {
throw new InvalidRequestException("Operation ID mismatch for credential and OTP: " + request.getCredentialName() + ", " + otp.getOtpDefinition().getName());
throw new InvalidRequestException("Operation ID mismatch for credential and OTP: " + otp.getCredentialDefinition().getName() + ", " + otp.getOtpDefinition().getName());
}
final CredentialEntity credential = credentialService.findCredential(otp.getCredentialDefinition(), user);
final CredentialDefinitionEntity credentialDefinition = credential.getCredentialDefinition();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,15 @@ public void testCredentialFailUnknownUser() {
@Test
public void testCredentialAndOtpSuccessNoOperation() throws NextStepClientException {
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "s3cret", r1.getOtpId(), r1.getOtpValue()).getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "s3cret", r1.getOtpId(), r1.getOtpValue()).getResponseObject();
assertEquals(AuthenticationResult.SUCCEEDED, r2.getAuthenticationResult());
}

@Test
public void testCredentialAndOtpSuccessWithOperation() throws NextStepClientException {
nextStepClient.createOperation("auth_otp", "test_operation_8", "A1", null, null);
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA", "test_operation_8").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "s3cret", r1.getOtpId(), "test_operation_8", r1.getOtpValue(), true, null).getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "s3cret", r1.getOtpId(), "test_operation_8", r1.getOtpValue(), true, null).getResponseObject();
assertEquals(AuthenticationResult.SUCCEEDED, r2.getAuthenticationResult());
GetOperationDetailResponse r3 = nextStepClient.getOperationDetail("test_operation_8").getResponseObject();
assertEquals(AuthResult.DONE, r3.getResult());
Expand All @@ -300,7 +300,7 @@ public void testCredentialAndOtpSuccessWithOperation() throws NextStepClientExce
@Test
public void testCredentialAndOtpFailNoOperation1() throws NextStepClientException {
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "secret", r1.getOtpId(), r1.getOtpValue()).getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "secret", r1.getOtpId(), r1.getOtpValue()).getResponseObject();
assertEquals(AuthenticationResult.FAILED, r2.getAuthenticationResult());
assertEquals(AuthenticationResult.FAILED, r2.getCredentialAuthenticationResult());
assertEquals(AuthenticationResult.SUCCEEDED, r2.getOtpAuthenticationResult());
Expand All @@ -309,7 +309,7 @@ public void testCredentialAndOtpFailNoOperation1() throws NextStepClientExceptio
@Test
public void testCredentialAndOtpFailNoOperation2() throws NextStepClientException {
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "s3cret", r1.getOtpId(), "0000000000").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "s3cret", r1.getOtpId(), "0000000000").getResponseObject();
assertEquals(AuthenticationResult.FAILED, r2.getAuthenticationResult());
assertEquals(AuthenticationResult.SUCCEEDED, r2.getCredentialAuthenticationResult());
assertEquals(AuthenticationResult.FAILED, r2.getOtpAuthenticationResult());
Expand All @@ -319,7 +319,7 @@ public void testCredentialAndOtpFailNoOperation2() throws NextStepClientExceptio
public void testCredentialAndOtpFailWithOperation1() throws NextStepClientException {
nextStepClient.createOperation("auth_otp", "test_operation_9a", "A1", null, null);
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA", "test_operation_9a").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "secret", r1.getOtpId(), "test_operation_9a", r1.getOtpValue(), true, null).getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "secret", r1.getOtpId(), "test_operation_9a", r1.getOtpValue(), true, null).getResponseObject();
assertEquals(AuthenticationResult.FAILED, r2.getAuthenticationResult());
assertEquals(AuthenticationResult.FAILED, r2.getCredentialAuthenticationResult());
assertEquals(AuthenticationResult.SUCCEEDED, r2.getOtpAuthenticationResult());
Expand All @@ -331,7 +331,7 @@ public void testCredentialAndOtpFailWithOperation1() throws NextStepClientExcept
public void testCredentialAndOtpFailWithOperation2() throws NextStepClientException {
nextStepClient.createOperation("auth_otp", "test_operation_9b", "A1", null, null);
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA", "test_operation_9b").getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "s3cret", r1.getOtpId(), "test_operation_9b", "0000000000", true, null).getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "s3cret", r1.getOtpId(), "test_operation_9b", "0000000000", true, null).getResponseObject();
assertEquals(AuthenticationResult.FAILED, r2.getAuthenticationResult());
assertEquals(AuthenticationResult.SUCCEEDED, r2.getCredentialAuthenticationResult());
assertEquals(AuthenticationResult.FAILED, r2.getOtpAuthenticationResult());
Expand Down Expand Up @@ -416,9 +416,9 @@ public void testCredentialVerifyBlockedUser() throws NextStepClientException {

@Test
public void testOtpAndCredentialVerifyBlockedUser() throws NextStepClientException {
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", null, "TEST_DATA").getResponseObject();
CreateOtpResponse r1 = nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA").getResponseObject();
nextStepClient.blockUser("test_user_1");
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "s3cret", r1.getOtpId(), r1.getOtpValue()).getResponseObject();
CombinedAuthenticationResponse r2 = nextStepClient.authenticateCombined("test_user_1", "s3cret", r1.getOtpId(), r1.getOtpValue()).getResponseObject();
assertEquals(UserIdentityStatus.BLOCKED, r2.getUserIdentityStatus());
assertEquals(AuthenticationResult.FAILED, r2.getAuthenticationResult());
assertEquals(AuthenticationResult.FAILED, r2.getOtpAuthenticationResult());
Expand Down Expand Up @@ -534,7 +534,7 @@ public void testOperationMaxAuthFailsCombined() throws NextStepClientException {
nextStepClient.createOperation("auth_otp", "test_operation_11", "A1", null, null);
for (int i = 0; i < 4; i++) {
nextStepClient.createOtp("test_user_1", "TEST_OTP", "TEST_CREDENTIAL", "TEST_DATA", "test_operation_11");
CombinedAuthenticationResponse r1 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "secret", null, "test_operation_11", "0000000000", true, null).getResponseObject();
CombinedAuthenticationResponse r1 = nextStepClient.authenticateCombined("test_user_1", "secret", null, "test_operation_11", "0000000000", true, null).getResponseObject();
assertEquals(AuthenticationResult.FAILED, r1.getAuthenticationResult());
if (i < 3) {
// 2 attempts for OTP, 2 attempts for credential
Expand All @@ -549,7 +549,7 @@ public void testOperationMaxAuthFailsCombined() throws NextStepClientException {
nextStepClient.updateCredentialCounter("test_user_1", "TEST_CREDENTIAL", AuthenticationResult.SUCCEEDED);
}
// Operation status changes to FAILED due to 5th failed attempt
CombinedAuthenticationResponse r1 = nextStepClient.authenticateCombined("TEST_CREDENTIAL", "test_user_1", "secret", null, "test_operation_11", "0000000000", true, null).getResponseObject();
CombinedAuthenticationResponse r1 = nextStepClient.authenticateCombined("test_user_1", "secret", null, "test_operation_11", "0000000000", true, null).getResponseObject();
assertEquals(0, (int) r1.getRemainingAttempts());
assertTrue(r1.isOperationFailed());
assertEquals(AuthenticationResult.FAILED, r1.getAuthenticationResult());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ protected AuthResultDetail authenticate(SmsAuthorizationRequest request) throws
final String otpId = getOtpIdFromHttpSession();
GetOrganizationDetailResponse organization = nextStepClient.getOrganizationDetail(operation.getOrganizationId()).getResponseObject();
String otpName = organization.getDefaultOtpName();
String credentialName = organization.getDefaultCredentialName();
if (otpName == null) {
logger.warn("Default OTP name is not configured for organization: " + operation.getOrganizationId());
throw new AuthStepException("SMS delivery failed", "error.communication");
Expand Down Expand Up @@ -217,7 +216,7 @@ protected AuthResultDetail authenticate(SmsAuthorizationRequest request) throws
}

String protectedPassword = passwordProtection.protect(request.getPassword());
CombinedAuthenticationResponse authResponse = nextStepClient.authenticateCombined(credentialName, userId, protectedPassword, otpId, operationId, authCode, true, authMethod).getResponseObject();
CombinedAuthenticationResponse authResponse = nextStepClient.authenticateCombined(userId, protectedPassword, otpId, operationId, authCode, true, authMethod).getResponseObject();
if (authResponse.isOperationFailed()) {
logger.info("Step authentication maximum attempts reached for credential and OTP verification (2FA) due to failed operation, operation ID: {}, authentication method: {}", operation.getOperationId(), authMethod);
throw new MaxAttemptsExceededException("Maximum number of authentication attempts exceeded");
Expand Down

0 comments on commit df72894

Please sign in to comment.