Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve OIDC code flow tests #27968

Merged
merged 1 commit into from Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -250,7 +250,7 @@ public Uni<? extends SecurityIdentity> apply(Throwable t) {
}
if (!configContext.oidcConfig.token.refreshExpired) {
LOG.debug("Token has expired, token refresh is not allowed");
throw new AuthenticationCompletionException(t.getCause());
throw new AuthenticationFailedException(t.getCause());
}
LOG.debug("Token has expired, trying to refresh it");
return refreshSecurityIdentity(configContext,
Expand Down Expand Up @@ -833,7 +833,7 @@ private Uni<SecurityIdentity> refreshSecurityIdentity(TenantConfigContext config
@Override
public Uni<SecurityIdentity> apply(final AuthorizationCodeTokens tokens, final Throwable t) {
if (t != null) {
LOG.debugf("ID token refresh has failed: %s", t.getMessage());
LOG.errorf("ID token refresh has failed: %s", t.getMessage());
if (autoRefresh) {
LOG.debug("Using the current SecurityIdentity since the ID token is still valid");
return Uni.createFrom().item(((TokenAutoRefreshException) t).getSecurityIdentity());
Expand Down
Expand Up @@ -174,12 +174,6 @@ public String getNameCallbackJwtNotUsedAfterRedirect() {
throw new InternalServerErrorException("This method must not be invoked");
}

@GET
@Path("tenant-logout")
public String getTenantLogout() {
return "Tenant Logout";
}

@GET
@Path("access")
public String getAccessToken() {
Expand Down
@@ -1,15 +1,20 @@
package io.quarkus.it.keycloak;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import io.quarkus.security.Authenticated;
import io.vertx.ext.web.RoutingContext;

@Path("/tenant-autorefresh")
public class TenantAutoRefresh {
@Inject
RoutingContext context;

@Authenticated
@GET
public String getTenantLogout() {
return "Tenant AutoRefresh";
return "Tenant AutoRefresh, refreshed: " + (context.get("refresh_token_grant_response") != null);
}
}
@@ -1,5 +1,6 @@
package io.quarkus.it.keycloak;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.Path;
Expand All @@ -9,17 +10,21 @@
import javax.ws.rs.core.HttpHeaders;

import io.quarkus.security.Authenticated;
import io.vertx.ext.web.RoutingContext;

@Path("/tenant-logout")
public class TenantLogout {

@Context
HttpHeaders headers;

@Inject
RoutingContext context;

@Authenticated
@GET
public String getTenantLogout() {
return "Tenant Logout";
return "Tenant Logout, refreshed: " + (context.get("refresh_token_grant_response") != null);
}

// It is needed for the proactive-auth=false to work: /tenant-logout/logout should match a user initiated logout request
Expand Down
Expand Up @@ -86,6 +86,7 @@ quarkus.oidc.tenant-autorefresh.application-type=web-app
quarkus.oidc.tenant-autorefresh.authentication.cookie-path=/tenant-autorefresh
quarkus.oidc.tenant-autorefresh.token.refresh-expired=true
quarkus.oidc.tenant-autorefresh.token.refresh-token-time-skew=30S
quarkus.oidc.tenant-autorefresh.authentication.remove-redirect-parameters=false

# Tenant which is used to test that the redirect_uri https scheme is enforced.
quarkus.oidc.tenant-https.auth-server-url=${keycloak.url}/realms/quarkus
Expand Down
Expand Up @@ -413,7 +413,7 @@ public void testRPInitiatedLogout() throws IOException {
loginForm.getInputByName("username").setValueAttribute("alice");
loginForm.getInputByName("password").setValueAttribute("alice");
page = loginForm.getInputByName("login").click();
assertTrue(page.asText().contains("Tenant Logout"));
assertEquals("Tenant Logout, refreshed: false", page.asText());
assertNotNull(getSessionCookie(webClient, "tenant-logout"));

page = webClient.getPage("http://localhost:8081/tenant-logout/logout");
Expand All @@ -422,11 +422,20 @@ public void testRPInitiatedLogout() throws IOException {

page = webClient.getPage("http://localhost:8081/tenant-logout");
assertEquals("Sign in to logout-realm", page.getTitleText());
loginForm = page.getForms().get(0);
webClient.getCookieManager().clearCookies();
}
}

@Test
public void testTokenRefresh() throws IOException {
try (final WebClient webClient = createWebClient()) {
HtmlPage page = webClient.getPage("http://localhost:8081/tenant-logout");
assertEquals("Sign in to logout-realm", page.getTitleText());
HtmlForm loginForm = page.getForms().get(0);
loginForm.getInputByName("username").setValueAttribute("alice");
loginForm.getInputByName("password").setValueAttribute("alice");
page = loginForm.getInputByName("login").click();
assertTrue(page.asText().contains("Tenant Logout"));
assertEquals("Tenant Logout, refreshed: false", page.asText());

Cookie sessionCookie = getSessionCookie(webClient, "tenant-logout");
assertNotNull(sessionCookie);
Expand All @@ -445,13 +454,14 @@ public Boolean call() throws Exception {
// Should not redirect to OP but silently refresh token
Cookie newSessionCookie = getSessionCookie(webClient, "tenant-logout");
assertNotNull(newSessionCookie);
return !idToken.equals(getIdToken(newSessionCookie));
return webResponse.getContentAsString().equals("Tenant Logout, refreshed: true")
&& !idToken.equals(getIdToken(newSessionCookie));
}
});

// local session refreshed and still valid
page = webClient.getPage("http://localhost:8081/tenant-logout");
assertTrue(page.asText().contains("Tenant Logout"));
assertEquals("Tenant Logout, refreshed: false", page.asText());
assertNotNull(getSessionCookie(webClient, "tenant-logout"));

//wait now so that we reach the refresh timeout
Expand Down Expand Up @@ -495,7 +505,7 @@ public void testTokenAutoRefresh() throws IOException {
loginForm.getInputByName("username").setValueAttribute("alice");
loginForm.getInputByName("password").setValueAttribute("alice");
page = loginForm.getInputByName("login").click();
assertTrue(page.asText().contains("Tenant AutoRefresh"));
assertEquals("Tenant AutoRefresh, refreshed: false", page.asText());

Cookie sessionCookie = getSessionCookie(webClient, "tenant-autorefresh");
assertNotNull(sessionCookie);
Expand All @@ -504,24 +514,11 @@ public void testTokenAutoRefresh() throws IOException {
// Auto-refresh-interval is 30 secs so every call auto-refreshes the token
// Right now the original ID token is still valid but will be auto-refreshed
page = webClient.getPage("http://localhost:8081/tenant-autorefresh");
assertTrue(page.getBody().asText().contains("Tenant AutoRefresh"));
assertEquals("Tenant AutoRefresh, refreshed: true", page.asText());
sessionCookie = getSessionCookie(webClient, "tenant-autorefresh");
assertNotNull(sessionCookie);
String nextIdToken = getIdToken(sessionCookie);
assertNotEquals(idToken, nextIdToken);
idToken = nextIdToken;

//wait now so that we reach the ID token timeout
await().atLeast(6, TimeUnit.SECONDS);

// ID token has expired, must be refreshed, auto-refresh-interval must not cause
// an auto-refresh loop even though it is larger than the ID token lifespan
page = webClient.getPage("http://localhost:8081/tenant-autorefresh");
assertTrue(page.getBody().asText().contains("Tenant AutoRefresh"));
sessionCookie = getSessionCookie(webClient, "tenant-autorefresh");
assertNotNull(sessionCookie);
nextIdToken = getIdToken(sessionCookie);
assertNotEquals(idToken, nextIdToken);

webClient.getCookieManager().clearCookies();
}
Expand Down