use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.
the class LoginController method casLoginResponse.
/**
* Redirect to FE, after CAS authentication.
*
* @return redirect to FE
* @since 12.0.0
*/
@RequestMapping(path = CAS_LOGIN_RESPONSE_PATH, method = RequestMethod.GET)
public ResponseEntity<Void> casLoginResponse() {
// process ticket + add token into url parameter
IdmTokenDto currentToken = tokenManager.getCurrentToken();
StringBuilder url = new StringBuilder(configurationService.getFrontendUrl(CAS_LOGIN_RESPONSE_PATH));
// set token into url - ok
if (currentToken != null) {
IdmJwtAuthentication authentication = jwtTokenMapper.fromDto(currentToken);
url.append('?');
url.append(JwtAuthenticationMapper.AUTHENTICATION_TOKEN_NAME.toLowerCase());
url.append('=');
url.append(jwtTokenMapper.writeToken(authentication));
} else if (ctx != null) {
// not - ok => resolve exception
ResultCodeException resultCodeException = ctx.getCodeEx();
if (resultCodeException == null) {
// resolve concrete exception
url.append("?status-code=");
if (ctx.getAuthEx() instanceof IdentityNotFoundException) {
// same as from standard login
url.append(CoreResultCode.AUTH_FAILED.getCode().toLowerCase());
} else if (ctx.getAuthEx() instanceof IdentityDisabledException) {
// same as from standard login
url.append(CoreResultCode.AUTH_FAILED.getCode().toLowerCase());
} else if (ctx.getAuthEx() instanceof CasTicketValidationException) {
url.append(CoreResultCode.CAS_TICKET_VALIDATION_FAILED.getCode().toLowerCase());
} else {
// common error - login failed
url.append(CoreResultCode.LOG_IN_FAILED.getCode().toLowerCase());
}
} else if (resultCodeException instanceof TwoFactorAuthenticationRequiredException) {
// handle two factor login
url.append('?');
url.append(JwtAuthenticationMapper.AUTHENTICATION_TOKEN_NAME.toLowerCase());
url.append('=');
url.append(((TwoFactorAuthenticationRequiredException) resultCodeException).getToken());
} else {
// concrete status code form result code exception
url.append("?status-code=");
url.append(resultCodeException.getError().getError().getStatusEnum().toLowerCase());
}
}
//
return ResponseEntity.status(HttpStatus.FOUND).header(HttpHeaders.LOCATION, url.toString()).build();
}
use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.
the class BasicIdmAuthenticationFilter method authorize.
@Override
public boolean authorize(String token, HttpServletRequest req, HttpServletResponse res) {
try {
LoginDto loginDto = createLoginDto(getBasicCredentials(token));
authManager.authenticate(loginDto);
LOG.debug("User [{}] successfully logged in.", loginDto.getUsername());
return true;
} catch (MustChangePasswordException | TwoFactorAuthenticationRequiredException ex) {
// publish additional authentication requirement
throw ex;
} catch (IdmAuthenticationException e) {
LOG.warn("Authentication exception raised during basic authentication: [{}].", e.getMessage());
} catch (Exception e) {
LOG.warn("Exception was raised during basic authentication: [{}].", e.getMessage());
}
return false;
}
use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.
the class CasAuthenticationFilter method authorize.
@Override
public boolean authorize(String token, HttpServletRequest request, HttpServletResponse response) {
String casUrl = casConfiguration.getUrl();
String service = casConfiguration.getService(request, true);
//
if (StringUtils.isBlank(casUrl)) {
LOG.info("URL for CAS is not set in configuration [{}], CAS authentication will be skipped.", CasConfiguration.PROPERTY_URL);
return false;
}
//
try {
if (StringUtils.isBlank(token)) {
LOG.info("No token from CAS");
return false;
}
Assertion assertion = validationService.validate(token, service, casUrl);
if (assertion == null) {
LOG.info("No principal name.");
return false;
}
if (!assertion.isValid()) {
LOG.debug("CAS Ticket [{}] validation failed.", token);
//
throw new CasTicketValidationException(MessageFormat.format("CAS Ticket [{0}] validation failed.", token));
}
//
String userName = assertion.getPrincipal().getName();
LOG.debug("Username found [{}]", userName);
//
IdmIdentityDto identity = identityService.getByUsername(userName);
if (identity == null) {
throw new IdentityNotFoundException(MessageFormat.format("Check identity can login: The identity " + "[{0}] either doesn't exist or is deleted.", userName));
}
// identity is valid
if (identity.isDisabled()) {
throw new IdentityDisabledException(MessageFormat.format("Check identity can login: The identity [{0}] is disabled.", userName));
}
LoginDto loginDto = jwtAuthenticationService.createJwtAuthenticationAndAuthenticate(createLoginDto(userName), identity, CoreModuleDescriptor.MODULE_ID);
//
LOG.debug("User [{}] successfully logged in.", loginDto.getUsername());
return true;
} catch (TwoFactorAuthenticationRequiredException ex) {
// must change password exception is never thrown
ctx.setCodeEx(ex);
// publish additional authentication requirement
throw ex;
} catch (IdmAuthenticationException ex) {
ctx.setAuthEx(ex);
LOG.warn("Authentication exception raised during CAS authentication: [{}].", ex.getMessage(), ex);
} catch (Exception ex) {
LOG.error("Exception was raised during CAS authentication: [{}].", ex.getMessage(), ex);
}
//
return false;
}
use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.
the class DefaultTwoFactorAuthenticationManagerIntegrationTest method testAuthenticateMustChangePasswordIsSkipped.
@Test
public void testAuthenticateMustChangePasswordIsSkipped() {
// 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()));
loginDto.setSkipMustChange(true);
LoginDto authenticated = manager.authenticate(loginDto);
//
Assert.assertNotNull(authenticated);
Assert.assertNotNull(authenticated.getAuthentication());
Assert.assertTrue(tokenManager.getToken(authenticated.getAuthentication().getId()).isSecretVerified());
}
use of eu.bcvsolutions.idm.core.security.api.exception.TwoFactorAuthenticationRequiredException in project CzechIdMng by bcvsolutions.
the class DefaultTwoFactorAuthenticationManagerIntegrationTest method testAuthenticateTokenNotExpired.
@Test
public void testAuthenticateTokenNotExpired() 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().plusDays(1));
token = jwtAuthenticationMapper.writeToken(jwt);
//
loginDto.setToken(token);
loginDto.setPassword(manager.generateCode(identity.getId()));
//
LoginDto authenticated = manager.authenticate(loginDto);
//
Assert.assertNotNull(authenticated);
Assert.assertNotNull(authenticated.getAuthentication());
Assert.assertTrue(tokenManager.getToken(authenticated.getAuthentication().getId()).isSecretVerified());
}
Aggregations