Search in sources :

Example 36 with VerificationException

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;
}
Also used : UserModel(org.keycloak.models.UserModel) ClientModel(org.keycloak.models.ClientModel) UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) VerificationException(org.keycloak.common.VerificationException) UserSessionCrossDCManager(org.keycloak.services.managers.UserSessionCrossDCManager)

Example 37 with VerificationException

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;
}
Also used : RealmModel(org.keycloak.models.RealmModel) SignatureProvider(org.keycloak.crypto.SignatureProvider) SignatureVerifierContext(org.keycloak.crypto.SignatureVerifierContext) AccessToken(org.keycloak.representations.AccessToken) VerificationException(org.keycloak.common.VerificationException)

Example 38 with VerificationException

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));
}
Also used : MimeMessage(javax.mail.internet.MimeMessage) AccessToken(org.keycloak.representations.AccessToken) UserResource(org.keycloak.admin.client.resource.UserResource) VerificationException(org.keycloak.common.VerificationException) IOException(java.io.IOException) LinkedList(java.util.LinkedList) UserRepresentation(org.keycloak.representations.idm.UserRepresentation) MailUtils(org.keycloak.testsuite.util.MailUtils) AuthServerContainerExclude(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude) Test(org.junit.Test)

Example 39 with VerificationException

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));
}
Also used : UserResource(org.keycloak.admin.client.resource.UserResource) IOException(java.io.IOException) LinkedList(java.util.LinkedList) ClientRepresentation(org.keycloak.representations.idm.ClientRepresentation) Response(javax.ws.rs.core.Response) MimeMessage(javax.mail.internet.MimeMessage) ErrorRepresentation(org.keycloak.representations.idm.ErrorRepresentation) AccessToken(org.keycloak.representations.AccessToken) ClientErrorException(javax.ws.rs.ClientErrorException) VerificationException(org.keycloak.common.VerificationException) UserRepresentation(org.keycloak.representations.idm.UserRepresentation) MailUtils(org.keycloak.testsuite.util.MailUtils) AuthServerContainerExclude(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude) Test(org.junit.Test)

Example 40 with VerificationException

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();
}
Also used : VerificationException(org.keycloak.common.VerificationException) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) VerificationException(org.keycloak.common.VerificationException) CertificateException(java.security.cert.CertificateException) ParsingException(org.keycloak.saml.common.exceptions.ParsingException)

Aggregations

VerificationException (org.keycloak.common.VerificationException)41 AccessToken (org.keycloak.representations.AccessToken)17 Test (org.junit.Test)8 JWSBuilder (org.keycloak.jose.jws.JWSBuilder)8 IOException (java.io.IOException)7 ClientModel (org.keycloak.models.ClientModel)7 SignatureProvider (org.keycloak.crypto.SignatureProvider)6 SignatureVerifierContext (org.keycloak.crypto.SignatureVerifierContext)6 UserSessionModel (org.keycloak.models.UserSessionModel)6 Response (javax.ws.rs.core.Response)4 OAuthErrorException (org.keycloak.OAuthErrorException)4 JWSInput (org.keycloak.jose.jws.JWSInput)4 UserModel (org.keycloak.models.UserModel)4 PublicKey (java.security.PublicKey)3 TokenVerifier (org.keycloak.TokenVerifier)3 AuthenticatedClientSessionModel (org.keycloak.models.AuthenticatedClientSessionModel)3 IDToken (org.keycloak.representations.IDToken)3 ConfigurationException (org.keycloak.saml.common.exceptions.ConfigurationException)3 ProcessingException (org.keycloak.saml.common.exceptions.ProcessingException)3 SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)3