Search in sources :

Example 6 with TwoFactorAuthenticationRequiredException

use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.

the class DefaultTwoFactorAuthenticationManagerIntegrationTest method testAuthenticateMustChangePassword.

@Test(expected = MustChangePasswordException.class)
public void testAuthenticateMustChangePassword() {
    // password is needed
    IdmIdentityDto identity = getHelper().createIdentity();
    IdmPasswordDto password = passwordService.findOneByIdentity(identity.getId());
    password.setMustChange(true);
    passwordService.save(password);
    // 
    TwoFactorRegistrationResponseDto initResponse = manager.init(identity.getId(), TwoFactorAuthenticationType.NOTIFICATION);
    Assert.assertNotNull(initResponse);
    Assert.assertNotNull(initResponse.getVerificationSecret());
    Assert.assertEquals(identity.getUsername(), initResponse.getUsername());
    Assert.assertNull(initResponse.getQrcode());
    // 
    // confirm
    TwoFactorRegistrationConfirmDto confirm = new TwoFactorRegistrationConfirmDto();
    confirm.setVerificationSecret(new GuardedString(initResponse.getVerificationSecret()));
    confirm.setVerificationCode(manager.generateCode(new GuardedString(initResponse.getVerificationSecret())));
    confirm.setTwoFactorAuthenticationType(TwoFactorAuthenticationType.NOTIFICATION);
    Assert.assertTrue(manager.confirm(identity.getId(), confirm));
    Assert.assertEquals(initResponse.getVerificationSecret(), getHelper().getPassword(identity).getVerificationSecret());
    // 
    LoginDto loginDto = new LoginDto();
    loginDto.setUsername(identity.getUsername());
    loginDto.setPassword(identity.getPassword());
    // creadentials are valid
    Assert.assertTrue(authenticationManager.validate(loginDto));
    // but two factor authentication is required
    String token = null;
    try {
        authenticationManager.authenticate(loginDto);
    } catch (TwoFactorAuthenticationRequiredException ex) {
        token = ex.getToken();
    }
    Assert.assertNotNull(token);
    // 
    loginDto.setToken(token);
    loginDto.setPassword(manager.generateCode(identity.getId()));
    manager.authenticate(loginDto);
}
Also used : TwoFactorRegistrationConfirmDto(eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationConfirmDto) TwoFactorRegistrationResponseDto(eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationResponseDto) IdmPasswordDto(eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) IdmIdentityDto(eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto) LoginDto(eu.bcvsolutions.idm.core.security.api.dto.LoginDto) TwoFactorAuthenticationRequiredException(eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException) AbstractIntegrationTest(eu.bcvsolutions.idm.test.api.AbstractIntegrationTest) Test(org.junit.Test)

Example 7 with TwoFactorAuthenticationRequiredException

use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.

the class DefaultAuthenticationManager method authenticate.

@Override
public LoginDto authenticate(LoginDto loginDto) {
    List<LoginDto> resultsList = new LinkedList<>();
    RuntimeException firstFailure = null;
    String logAction = siemLogger.buildAction(SiemLoggerManager.LOGIN_LEVEL_KEY, SiemLoggerManager.LOGIN_SUBLEVEL_KEY);
    IdmIdentityDto identity = identityService.getByUsername(loginDto.getUsername());
    if (identity == null) {
        // just for logging purpose
        identity = new IdmIdentityDto();
        identity.setUsername(loginDto.getUsername());
    }
    // check if user can log in and hasn't administrator permission
    try {
        IdmPasswordDto passwordDto = passwordService.findOrCreateByIdentity(loginDto.getUsername());
        if (passwordDto == null) {
            throw new ResultCodeException(CoreResultCode.AUTH_FAILED, "Invalid login or password.");
        }
        if (passwordDto.getBlockLoginDate() != null && passwordDto.getBlockLoginDate().isAfter(ZonedDateTime.now())) {
            LOG.info("Identity {} has blocked login to IdM.", loginDto.getUsername());
            IdmIdentityDto identityDto = DtoUtils.getEmbedded(passwordDto, IdmPassword_.identity);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(configurationService.getDateTimeSecondsFormat());
            ZonedDateTime blockLoginDate = passwordDto.getBlockLoginDate();
            String dateAsString = blockLoginDate.format(formatter);
            // Block login date can be set manually by password metadata,
            // so block login date can be more than int amount.
            long blockMillies = blockLoginDate.toInstant().toEpochMilli();
            long nowMillis = ZonedDateTime.now().toInstant().toEpochMilli();
            long different = blockMillies - nowMillis;
            different = different / 1000;
            throw new ResultCodeException(CoreResultCode.AUTH_BLOCKED, ImmutableMap.of("username", identityDto.getUsername(), "date", dateAsString, "seconds", different, "unsuccessfulAttempts", passwordDto.getUnsuccessfulAttempts()));
        }
        // 
        for (Authenticator authenticator : getEnabledAuthenticators()) {
            LOG.debug("AuthenticationManager call authenticate by [{}].", authenticator.getName());
            try {
                LoginDto result = authenticator.authenticate(cloneLoginDto(loginDto));
                if (result == null) {
                    // continue, authenticator is not implemented or etc.
                    continue;
                }
                if (authenticator.getExceptedResult() == AuthenticationResponseEnum.SUFFICIENT) {
                    checkAdditionalAuthenticationRequirements(passwordDto, result);
                    passwordDto = passwordService.setLastSuccessfulLogin(passwordDto);
                    siemLogger.log(logAction, SiemLoggerManager.SUCCESS_ACTION_STATUS, identity, null, null, null);
                    return result;
                }
                // if otherwise add result too list and continue
                resultsList.add(result);
            } catch (MustChangePasswordException | TwoFactorAuthenticationRequiredException ex) {
                // publish additional authentication requirement
                throw ex;
            } catch (RuntimeException e) {
                // if excepted response is REQUISITE exit immediately with error
                if (authenticator.getExceptedResult() == AuthenticationResponseEnum.REQUISITE) {
                    blockLogin(passwordDto, loginDto);
                    // 
                    throw e;
                }
                // if otherwise save first failure into exception
                if (firstFailure == null) {
                    firstFailure = e;
                }
            }
        }
        // authenticator is sorted by implement ordered, return first success authenticate authenticator, if don't exist any otherwise throw first failure
        if (resultsList.isEmpty()) {
            blockLogin(passwordDto, loginDto);
            throw firstFailure;
        }
        // 
        LoginDto result = resultsList.get(0);
        checkAdditionalAuthenticationRequirements(passwordDto, result);
        passwordDto = passwordService.setLastSuccessfulLogin(passwordDto);
        // 
        siemLogger.log(logAction, SiemLoggerManager.SUCCESS_ACTION_STATUS, identity, null, null, null);
        return result;
    } catch (TwoFactorAuthenticationRequiredException tfaEx) {
        // skip logging, 2FA is needed, result will be logged there
        throw tfaEx;
    } catch (Exception e) {
        siemLogger.log(logAction, SiemLoggerManager.FAILED_ACTION_STATUS, identity, null, null, e.getMessage());
        throw e;
    }
}
Also used : ResultCodeException(eu.bcvsolutions.idm.core.api.exception.ResultCodeException) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) LinkedList(java.util.LinkedList) TwoFactorAuthenticationRequiredException(eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException) ResultCodeException(eu.bcvsolutions.idm.core.api.exception.ResultCodeException) MustChangePasswordException(eu.bcvsolutions.idm.core.security.api.exception.MustChangePasswordException) MustChangePasswordException(eu.bcvsolutions.idm.core.security.api.exception.MustChangePasswordException) ZonedDateTime(java.time.ZonedDateTime) IdmPasswordDto(eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto) LoginDto(eu.bcvsolutions.idm.core.security.api.dto.LoginDto) IdmIdentityDto(eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto) DateTimeFormatter(java.time.format.DateTimeFormatter) Authenticator(eu.bcvsolutions.idm.core.security.api.authentication.Authenticator) TwoFactorAuthenticationRequiredException(eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException)

Example 8 with TwoFactorAuthenticationRequiredException

use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.

the class DefaultJwtAuthenticationService method createJwtAuthenticationAndAuthenticate.

@Override
public LoginDto createJwtAuthenticationAndAuthenticate(LoginDto loginDto, IdmIdentityDto identity, IdmTokenDto preparedToken) {
    Assert.notNull(identity, "Identity is required.");
    UUID identityId = identity.getId();
    Assert.notNull(identityId, "Identity identifier is required.");
    // check identity is valid
    if (identity.isDisabled()) {
        throw new IdentityDisabledException(MessageFormat.format("Check identity can login: The identity [{0}] is disabled.", identity.getUsername()));
    }
    // two factor authentication is not configured for given identity
    if (tokenManager.isNew(preparedToken)) {
        if (// public password change page => login is needed, before password is changed
        loginDto.isSkipMustChange() || twoFactorAuthenticationManager.getTwoFactorAuthenticationType(identityId) == null) {
            preparedToken.setSecretVerified(true);
        } else {
            // two factor needed
            preparedToken.setSecretVerified(false);
        }
    }
    // create token
    IdmTokenDto token = jwtTokenMapper.createToken(identity, preparedToken);
    // check two factor authentication is required
    if (twoFactorAuthenticationManager.requireTwoFactorAuthentication(identityId, token.getId())) {
        IdmJwtAuthenticationDto authenticationDto = jwtTokenMapper.toDto(token);
        // token is needed in exception => sso login can be used and client doesn't have token
        throw new TwoFactorAuthenticationRequiredException(jwtTokenMapper.writeToken(authenticationDto));
    }
    // 
    return login(loginDto, token);
}
Also used : IdentityDisabledException(eu.bcvsolutions.idm.core.security.api.exception.IdentityDisabledException) IdmTokenDto(eu.bcvsolutions.idm.core.api.dto.IdmTokenDto) IdmJwtAuthenticationDto(eu.bcvsolutions.idm.core.security.api.dto.IdmJwtAuthenticationDto) UUID(java.util.UUID) TwoFactorAuthenticationRequiredException(eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException)

Example 9 with TwoFactorAuthenticationRequiredException

use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.

the class DefaultTwoFactorAuthenticationManagerIntegrationTest method testAuthenticatePasswordIsDeleted.

@Test(expected = EntityNotFoundException.class)
public void testAuthenticatePasswordIsDeleted() {
    // password is needed
    IdmIdentityDto identity = getHelper().createIdentity();
    IdmPasswordDto password = passwordService.findOneByIdentity(identity.getId());
    // 
    TwoFactorRegistrationResponseDto initResponse = manager.init(identity.getId(), TwoFactorAuthenticationType.NOTIFICATION);
    Assert.assertNotNull(initResponse);
    Assert.assertNotNull(initResponse.getVerificationSecret());
    Assert.assertEquals(identity.getUsername(), initResponse.getUsername());
    Assert.assertNull(initResponse.getQrcode());
    // 
    // confirm
    TwoFactorRegistrationConfirmDto confirm = new TwoFactorRegistrationConfirmDto();
    confirm.setVerificationSecret(new GuardedString(initResponse.getVerificationSecret()));
    confirm.setVerificationCode(manager.generateCode(new GuardedString(initResponse.getVerificationSecret())));
    confirm.setTwoFactorAuthenticationType(TwoFactorAuthenticationType.NOTIFICATION);
    Assert.assertTrue(manager.confirm(identity.getId(), confirm));
    Assert.assertEquals(initResponse.getVerificationSecret(), getHelper().getPassword(identity).getVerificationSecret());
    // 
    LoginDto loginDto = new LoginDto();
    loginDto.setUsername(identity.getUsername());
    loginDto.setPassword(identity.getPassword());
    // creadentials are valid
    Assert.assertTrue(authenticationManager.validate(loginDto));
    // but two factor authentication is required
    String token = null;
    try {
        authenticationManager.authenticate(loginDto);
    } catch (TwoFactorAuthenticationRequiredException ex) {
        token = ex.getToken();
    }
    Assert.assertNotNull(token);
    // 
    loginDto.setToken(token);
    loginDto.setPassword(manager.generateCode(identity.getId()));
    // 
    // delete password
    passwordService.delete(password);
    // 
    manager.authenticate(loginDto);
}
Also used : TwoFactorRegistrationConfirmDto(eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationConfirmDto) TwoFactorRegistrationResponseDto(eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationResponseDto) IdmPasswordDto(eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) IdmIdentityDto(eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto) LoginDto(eu.bcvsolutions.idm.core.security.api.dto.LoginDto) TwoFactorAuthenticationRequiredException(eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException) AbstractIntegrationTest(eu.bcvsolutions.idm.test.api.AbstractIntegrationTest) Test(org.junit.Test)

Example 10 with TwoFactorAuthenticationRequiredException

use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.

the class DefaultTwoFactorAuthenticationManagerIntegrationTest method testAuthenticateTokenExpired.

@Test(expected = ResultCodeException.class)
public void testAuthenticateTokenExpired() throws Exception {
    // password is needed
    IdmIdentityDto identity = getHelper().createIdentity();
    // 
    TwoFactorRegistrationResponseDto initResponse = manager.init(identity.getId(), TwoFactorAuthenticationType.NOTIFICATION);
    Assert.assertNotNull(initResponse);
    Assert.assertNotNull(initResponse.getVerificationSecret());
    Assert.assertEquals(identity.getUsername(), initResponse.getUsername());
    Assert.assertNull(initResponse.getQrcode());
    // 
    // confirm
    TwoFactorRegistrationConfirmDto confirm = new TwoFactorRegistrationConfirmDto();
    confirm.setVerificationSecret(new GuardedString(initResponse.getVerificationSecret()));
    confirm.setVerificationCode(manager.generateCode(new GuardedString(initResponse.getVerificationSecret())));
    confirm.setTwoFactorAuthenticationType(TwoFactorAuthenticationType.NOTIFICATION);
    Assert.assertTrue(manager.confirm(identity.getId(), confirm));
    Assert.assertEquals(initResponse.getVerificationSecret(), getHelper().getPassword(identity).getVerificationSecret());
    // 
    LoginDto loginDto = new LoginDto();
    loginDto.setUsername(identity.getUsername());
    loginDto.setPassword(identity.getPassword());
    // creadentials are valid
    Assert.assertTrue(authenticationManager.validate(loginDto));
    // but two factor authentication is required
    String token = null;
    try {
        authenticationManager.authenticate(loginDto);
    } catch (TwoFactorAuthenticationRequiredException ex) {
        token = ex.getToken();
    }
    Assert.assertNotNull(token);
    // 
    // set token expiration
    IdmJwtAuthentication jwt = jwtAuthenticationMapper.readToken(token);
    jwt.setExpiration(ZonedDateTime.now().minusDays(1));
    token = jwtAuthenticationMapper.writeToken(jwt);
    // 
    loginDto.setToken(token);
    loginDto.setPassword(manager.generateCode(identity.getId()));
    // 
    manager.authenticate(loginDto);
}
Also used : TwoFactorRegistrationConfirmDto(eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationConfirmDto) TwoFactorRegistrationResponseDto(eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationResponseDto) IdmJwtAuthentication(eu.bcvsolutions.idm.core.security.api.domain.IdmJwtAuthentication) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) GuardedString(eu.bcvsolutions.idm.core.security.api.domain.GuardedString) IdmIdentityDto(eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto) LoginDto(eu.bcvsolutions.idm.core.security.api.dto.LoginDto) TwoFactorAuthenticationRequiredException(eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException) AbstractIntegrationTest(eu.bcvsolutions.idm.test.api.AbstractIntegrationTest) Test(org.junit.Test)

Aggregations

TwoFactorAuthenticationRequiredException (eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException)13 LoginDto (eu.bcvsolutions.idm.core.security.api.dto.LoginDto)11 IdmIdentityDto (eu.bcvsolutions.idm.core.api.dto.IdmIdentityDto)10 GuardedString (eu.bcvsolutions.idm.core.security.api.domain.GuardedString)9 TwoFactorRegistrationConfirmDto (eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationConfirmDto)8 TwoFactorRegistrationResponseDto (eu.bcvsolutions.idm.core.security.api.dto.TwoFactorRegistrationResponseDto)8 AbstractIntegrationTest (eu.bcvsolutions.idm.test.api.AbstractIntegrationTest)8 Test (org.junit.Test)8 IdmPasswordDto (eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto)4 IdmJwtAuthentication (eu.bcvsolutions.idm.core.security.api.domain.IdmJwtAuthentication)3 IdentityDisabledException (eu.bcvsolutions.idm.core.security.api.exception.IdentityDisabledException)3 IdmTokenDto (eu.bcvsolutions.idm.core.api.dto.IdmTokenDto)2 ResultCodeException (eu.bcvsolutions.idm.core.api.exception.ResultCodeException)2 CasTicketValidationException (eu.bcvsolutions.idm.core.security.api.exception.CasTicketValidationException)2 IdentityNotFoundException (eu.bcvsolutions.idm.core.security.api.exception.IdentityNotFoundException)2 IdmAuthenticationException (eu.bcvsolutions.idm.core.security.api.exception.IdmAuthenticationException)2 MustChangePasswordException (eu.bcvsolutions.idm.core.security.api.exception.MustChangePasswordException)2 Authenticator (eu.bcvsolutions.idm.core.security.api.authentication.Authenticator)1 IdmJwtAuthenticationDto (eu.bcvsolutions.idm.core.security.api.dto.IdmJwtAuthenticationDto)1 ZonedDateTime (java.time.ZonedDateTime)1