CookieTokenStoreAdapterTest.java
    
    
    
    
    
        Home
            /
testsuite                    /
integration                    /
src                    /
test                    /
java                    /
org                    /
keycloak                    /
testsuite                    /
adapter                    /
                    CookieTokenStoreAdapterTest.java
    
    
            
            package org.keycloak.testsuite.adapter;
import java.net.URL;
import javax.ws.rs.core.UriBuilder;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OpenIDConnectService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testutils.KeycloakServer;
import org.keycloak.util.Time;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
/**
 * KEYCLOAK-702
 *
 * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
 */
public class CookieTokenStoreAdapterTest {
    public static final String LOGIN_URL = OpenIDConnectService.loginPageUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build("demo").toString();
    @ClassRule
    public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
        @Override
        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
            // Other tests may left Time offset uncleared, which could cause issues
            Time.setOffset(0);
            RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
            manager.importRealm(representation);
            URL url = getClass().getResource("/adapter-test/cust-app-keycloak.json");
            deployApplication("customer-portal", "/customer-portal", CustomerServlet.class, url.getPath(), "user");
            url = getClass().getResource("/adapter-test/cust-app-cookie-keycloak.json");
            deployApplication("customer-cookie-portal", "/customer-cookie-portal", CustomerServlet.class, url.getPath(), "user");
            url = getClass().getResource("/adapter-test/customer-db-keycloak.json");
            deployApplication("customer-db", "/customer-db", CustomerDatabaseServlet.class, url.getPath(), "user");
        }
    };
    @Rule
    public WebRule webRule = new WebRule(this);
    @WebResource
    protected WebDriver driver;
    @WebResource
    protected OAuthClient oauth;
    @WebResource
    protected LoginPage loginPage;
    @Test
    public void testTokenInCookieSSO() throws Throwable {
        // Login
        String tokenCookie = loginToCustomerCookiePortal();
        // SSO to second app
        driver.navigate().to("http://localhost:8081/customer-portal");
        assertLogged();
        // return to customer-cookie-portal and assert still same cookie (accessToken didn't expire)
        driver.navigate().to("http://localhost:8081/customer-cookie-portal");
        assertLogged();
        String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
        Assert.assertEquals(tokenCookie, tokenCookie2);
        // Logout with httpServletRequest
        logoutFromCustomerCookiePortal();
        // Also should be logged-out from the second app
        driver.navigate().to("http://localhost:8081/customer-portal");
        Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
    }
    @Test
    public void testTokenInCookieRefresh() throws Throwable {
        try {
            // Set token timeout 1 sec
            KeycloakSession session = keycloakRule.startSession();
            RealmModel realm = session.realms().getRealmByName("demo");
            int originalTokenTimeout = realm.getAccessTokenLifespan();
            realm.setAccessTokenLifespan(3);
            session.getTransaction().commit();
            session.close();
            // login to customer-cookie-portal
            String tokenCookie1 = loginToCustomerCookiePortal();
            // Simulate waiting 4 seconds (Running testsuite in real env like Wildfly or EAP may still require to do Thread.sleep to really wait 4 seconds...)
            Time.setOffset(4);
            //Thread.sleep(4000);
            // assert cookie was refreshed
            driver.navigate().to("http://localhost:8081/customer-cookie-portal");
            Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-cookie-portal");
            assertLogged();
            String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
            Assert.assertNotEquals(tokenCookie1, tokenCookie2);
            // login to 2nd app and logout from it
            driver.navigate().to("http://localhost:8081/customer-portal");
            Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-portal");
            assertLogged();
            driver.navigate().to("http://localhost:8081/customer-portal/logout");
            Assert.assertTrue(driver.getPageSource().contains("servlet logout ok"));
            driver.navigate().to("http://localhost:8081/customer-portal");
            Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
            // Simulate another 4 seconds
            Time.setOffset(8);
            // assert not logged in customer-cookie-portal
            driver.navigate().to("http://localhost:8081/customer-cookie-portal");
            Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
            // Change timeout back
            Time.setOffset(0);
            session = keycloakRule.startSession();
            realm = session.realms().getRealmByName("demo");
            realm.setAccessTokenLifespan(originalTokenTimeout);
            session.getTransaction().commit();
            session.close();
        } finally {
            Time.setOffset(0);
        }
    }
    @Test
    public void testInvalidTokenCookie() throws Throwable {
        // Login
        String tokenCookie = loginToCustomerCookiePortal();
        String changedTokenCookie = tokenCookie.replace("a", "b");
        // change cookie to invalid value
        driver.manage().addCookie(new Cookie(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE, changedTokenCookie, "/customer-cookie-portal"));
        // visit page and assert re-logged and cookie was refreshed
        driver.navigate().to("http://localhost:8081/customer-cookie-portal");
        Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-cookie-portal");
        String currentCookie = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
        Assert.assertNotEquals(currentCookie, tokenCookie);
        Assert.assertNotEquals(currentCookie, changedTokenCookie);
        // logout
        logoutFromCustomerCookiePortal();
    }
    // login to customer-cookie-portal and return the KEYCLOAK_ADAPTER_STATE cookie established on adapter
    private String loginToCustomerCookiePortal() {
        driver.navigate().to("http://localhost:8081/customer-cookie-portal");
        Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
        loginPage.login("bburke@redhat.com", "password");
        Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-cookie-portal");
        assertLogged();
        // Assert no JSESSIONID cookie
        Assert.assertNull(driver.manage().getCookieNamed("JSESSIONID"));
        return driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
    }
    private void logoutFromCustomerCookiePortal() {
        driver.navigate().to("http://localhost:8081/customer-cookie-portal/logout");
        Assert.assertTrue(driver.getPageSource().contains("servlet logout ok"));
        Assert.assertNull(driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE));
        driver.navigate().to("http://localhost:8081/customer-cookie-portal");
        Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
    }
    private void assertLogged() {
        String pageSource = driver.getPageSource();
        Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
    }
}