use of org.keycloak.common.VerificationException in project keycloak by keycloak.
the class TokenManager method checkTokenValidForIntrospection.
/**
* Checks if the token is valid. Optionally the session last refresh and client session timestamp
* are updated if the token was valid. This is used to keep the session alive when long lived tokens are used.
*
* @param session
* @param realm
* @param token
* @param updateTimestamps
* @return
*/
public boolean checkTokenValidForIntrospection(KeycloakSession session, RealmModel realm, AccessToken token, boolean updateTimestamps) {
ClientModel client = realm.getClientByClientId(token.getIssuedFor());
if (client == null || !client.isEnabled()) {
return false;
}
try {
TokenVerifier.createWithoutSignature(token).withChecks(NotBeforeCheck.forModel(client), TokenVerifier.IS_ACTIVE, new TokenRevocationCheck(session)).verify();
} catch (VerificationException e) {
logger.debugf("JWT check failed: %s", e.getMessage());
return false;
}
boolean valid = false;
// Tokens without sessions are considered valid. Signature check and revocation check are sufficient checks for them
if (token.getSessionState() == null) {
UserModel user = lookupUserFromStatelessToken(session, realm, token);
valid = isUserValid(session, realm, token, user);
} else {
UserSessionModel userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), false, client.getId());
if (AuthenticationManager.isSessionValid(realm, userSession)) {
valid = isUserValid(session, realm, token, userSession.getUser());
} else {
userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), true, client.getId());
if (AuthenticationManager.isOfflineSessionValid(realm, userSession)) {
valid = isUserValid(session, realm, token, userSession.getUser());
}
}
if (valid && (token.isIssuedBeforeSessionStart(userSession.getStarted()))) {
valid = false;
}
AuthenticatedClientSessionModel clientSession = userSession == null ? null : userSession.getAuthenticatedClientSessionByClient(client.getId());
if (clientSession != null) {
if (valid && (token.isIssuedBeforeSessionStart(clientSession.getStarted()))) {
valid = false;
}
}
String tokenType = token.getType();
if (realm.isRevokeRefreshToken() && (tokenType.equals(TokenUtil.TOKEN_TYPE_REFRESH) || tokenType.equals(TokenUtil.TOKEN_TYPE_OFFLINE)) && !validateTokenReuseForIntrospection(session, realm, token)) {
return false;
}
if (updateTimestamps && valid) {
int currentTime = Time.currentTime();
userSession.setLastSessionRefresh(currentTime);
if (clientSession != null) {
clientSession.setTimestamp(currentTime);
}
}
}
return valid;
}
use of org.keycloak.common.VerificationException in project keycloak by keycloak.
the class AccessTokenIntrospectionProvider method verifyAccessToken.
protected AccessToken verifyAccessToken(String token) {
AccessToken accessToken;
try {
TokenVerifier<AccessToken> verifier = TokenVerifier.create(token, AccessToken.class).realmUrl(Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
SignatureVerifierContext verifierContext = session.getProvider(SignatureProvider.class, verifier.getHeader().getAlgorithm().name()).verifier(verifier.getHeader().getKeyId());
verifier.verifierContext(verifierContext);
accessToken = verifier.verify().getToken();
} catch (VerificationException e) {
logger.debugf("JWT check failed: %s", e.getMessage());
return null;
}
RealmModel realm = this.session.getContext().getRealm();
return tokenManager.checkTokenValidForIntrospection(session, realm, accessToken, false) ? accessToken : null;
}
use of org.keycloak.common.VerificationException in project keycloak by keycloak.
the class UserTest method sendResetPasswordEmailWithCustomLifespan.
@Test
@AuthServerContainerExclude(AuthServer.REMOTE)
public void sendResetPasswordEmailWithCustomLifespan() throws IOException {
UserRepresentation userRep = new UserRepresentation();
userRep.setEnabled(true);
userRep.setUsername("user1");
userRep.setEmail("user1@test.com");
String id = createUser(userRep);
UserResource user = realm.users().get(id);
List<String> actions = new LinkedList<>();
actions.add(UserModel.RequiredAction.UPDATE_PASSWORD.name());
final int lifespan = (int) TimeUnit.HOURS.toSeconds(5);
user.executeActionsEmail(actions, lifespan);
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResourcePath(id) + "/execute-actions-email", ResourceType.USER);
Assert.assertEquals(1, greenMail.getReceivedMessages().length);
MimeMessage message = greenMail.getReceivedMessages()[0];
MailUtils.EmailBody body = MailUtils.getBody(message);
assertTrue(body.getText().contains("Update Password"));
assertTrue(body.getText().contains("your Admin-client-test account"));
assertTrue(body.getText().contains("This link will expire within 5 hours"));
assertTrue(body.getHtml().contains("Update Password"));
assertTrue(body.getHtml().contains("your Admin-client-test account"));
assertTrue(body.getHtml().contains("This link will expire within 5 hours"));
String link = MailUtils.getPasswordResetEmailLink(body);
String token = link.substring(link.indexOf("key=") + "key=".length());
try {
final AccessToken accessToken = TokenVerifier.create(token, AccessToken.class).getToken();
assertEquals(lifespan, accessToken.getExpiration() - accessToken.getIssuedAt());
} catch (VerificationException e) {
throw new IOException(e);
}
driver.navigate().to(link);
proceedPage.assertCurrent();
assertThat(proceedPage.getInfo(), Matchers.containsString("Update Password"));
proceedPage.clickProceedLink();
passwordUpdatePage.assertCurrent();
passwordUpdatePage.changePassword("new-pass", "new-pass");
assertEquals("Your account has been updated.", PageUtils.getPageTitle(driver));
driver.navigate().to(link);
assertEquals("We are sorry...", PageUtils.getPageTitle(driver));
}
use of org.keycloak.common.VerificationException in project keycloak by keycloak.
the class UserTest method sendResetPasswordEmailWithRedirectAndCustomLifespan.
@Test
@AuthServerContainerExclude(AuthServer.REMOTE)
public void sendResetPasswordEmailWithRedirectAndCustomLifespan() throws IOException {
UserRepresentation userRep = new UserRepresentation();
userRep.setEnabled(true);
userRep.setUsername("user1");
userRep.setEmail("user1@test.com");
String id = createUser(userRep);
UserResource user = realm.users().get(id);
ClientRepresentation client = new ClientRepresentation();
client.setClientId("myclient");
client.setRedirectUris(new LinkedList<>());
client.getRedirectUris().add("http://myclient.com/*");
client.setName("myclient");
client.setEnabled(true);
Response response = realm.clients().create(client);
String createdId = ApiUtil.getCreatedId(response);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(createdId), client, ResourceType.CLIENT);
List<String> actions = new LinkedList<>();
actions.add(UserModel.RequiredAction.UPDATE_PASSWORD.name());
final int lifespan = (int) TimeUnit.DAYS.toSeconds(128);
try {
// test that an invalid redirect uri is rejected.
user.executeActionsEmail("myclient", "http://unregistered-uri.com/", lifespan, actions);
fail("Expected failure");
} catch (ClientErrorException e) {
assertEquals(400, e.getResponse().getStatus());
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
Assert.assertEquals("Invalid redirect uri.", error.getErrorMessage());
}
user.executeActionsEmail("myclient", "http://myclient.com/home.html", lifespan, actions);
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, AdminEventPaths.userResourcePath(id) + "/execute-actions-email", ResourceType.USER);
Assert.assertEquals(1, greenMail.getReceivedMessages().length);
MimeMessage message = greenMail.getReceivedMessages()[0];
MailUtils.EmailBody body = MailUtils.getBody(message);
assertTrue(body.getText().contains("This link will expire within 128 days"));
assertTrue(body.getHtml().contains("This link will expire within 128 days"));
String link = MailUtils.getPasswordResetEmailLink(message);
String token = link.substring(link.indexOf("key=") + "key=".length());
try {
final AccessToken accessToken = TokenVerifier.create(token, AccessToken.class).getToken();
assertEquals(lifespan, accessToken.getExpiration() - accessToken.getIssuedAt());
} catch (VerificationException e) {
throw new IOException(e);
}
driver.navigate().to(link);
proceedPage.assertCurrent();
assertThat(proceedPage.getInfo(), Matchers.containsString("Update Password"));
proceedPage.clickProceedLink();
passwordUpdatePage.assertCurrent();
passwordUpdatePage.changePassword("new-pass", "new-pass");
assertEquals("Your account has been updated.", driver.findElement(By.id("kc-page-title")).getText());
String pageSource = driver.getPageSource();
// check to make sure the back link is set.
Assert.assertTrue(pageSource.contains("http://myclient.com/home.html"));
driver.navigate().to(link);
assertEquals("We are sorry...", PageUtils.getPageTitle(driver));
}
use of org.keycloak.common.VerificationException in project keycloak by keycloak.
the class SamlProtocolUtils method getPublicKey.
private static PublicKey getPublicKey(String certPem) throws VerificationException {
if (certPem == null)
throw new VerificationException("Client does not have a public key.");
X509Certificate cert = null;
try {
cert = PemUtils.decodeCertificate(certPem);
cert.checkValidity();
} catch (CertificateException ex) {
throw new VerificationException("Certificate is not valid.");
} catch (Exception e) {
throw new VerificationException("Could not decode cert", e);
}
return cert.getPublicKey();
}
Aggregations