Skip to content

Commit

Permalink
Fire OIDC event when server not available
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Dec 14, 2023
1 parent ace2bbd commit 39a0e35
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public class SecurityEvent extends AbstractSecurityEvent {
public static final String SESSION_TOKENS_PROPERTY = "session-tokens";

public enum Type {
/**
* OIDC endpoint access event which is reported if an attempt to connect to the OIDC server failed.
*/
OIDC_SERVER_NOT_AVAILABLE,
/**
* OIDC Login event which is reported after the first user authentication but also when the user's session
* has expired and the user has re-authenticated at the OIDC provider site.
Expand Down Expand Up @@ -70,6 +74,11 @@ public SecurityEvent(Type eventType, Map<String, Object> eventProperties) {
this.eventType = eventType;
}

public SecurityEvent(Type eventType) {
super(null, null);
this.eventType = eventType;
}

public Type getEventType() {
return eventType;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.oidc.runtime;

import static io.quarkus.oidc.SecurityEvent.Type.OIDC_SERVER_NOT_AVAILABLE;
import static io.quarkus.oidc.runtime.OidcUtils.DEFAULT_TENANT_ID;
import static io.quarkus.vertx.http.runtime.security.HttpSecurityUtils.getRoutingContextAttribute;

Expand Down Expand Up @@ -28,6 +29,7 @@
import io.quarkus.oidc.OidcTenantConfig.ApplicationType;
import io.quarkus.oidc.OidcTenantConfig.Roles.Source;
import io.quarkus.oidc.OidcTenantConfig.TokenStateManager.Strategy;
import io.quarkus.oidc.SecurityEvent;
import io.quarkus.oidc.TenantConfigResolver;
import io.quarkus.oidc.TenantIdentityProvider;
import io.quarkus.oidc.common.OidcEndpoint;
Expand All @@ -42,8 +44,10 @@
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.quarkus.security.runtime.SecurityConfig;
import io.quarkus.security.spi.runtime.BlockingSecurityExecutor;
import io.quarkus.security.spi.runtime.MethodDescription;
import io.quarkus.security.spi.runtime.SecurityEventHelper;
import io.smallrye.jwt.algorithm.KeyEncryptionAlgorithm;
import io.smallrye.jwt.util.KeyUtils;
import io.smallrye.mutiny.Uni;
Expand Down Expand Up @@ -359,6 +363,7 @@ public static Optional<ProxyOptions> toProxyOptions(OidcCommonConfig.Proxy proxy
protected static OIDCException toOidcException(Throwable cause, String authServerUrl) {
final String message = OidcCommonUtils.formatConnectionErrorMessage(authServerUrl);
LOG.warn(message);
fireOidcServerNotAvailableEvent();
return new OIDCException("OIDC Server is not available", cause);
}

Expand Down Expand Up @@ -514,6 +519,14 @@ private static OidcConfigurationMetadata createLocalMetadata(OidcTenantConfig oi
oidcConfig.token.issuer.orElse(null));
}

private static void fireOidcServerNotAvailableEvent() {
if (Arc.container().instance(SecurityConfig.class).get().events().enabled()) {
SecurityEventHelper.fire(
Arc.container().beanManager().getEvent().select(SecurityEvent.class),
new SecurityEvent(OIDC_SERVER_NOT_AVAILABLE));
}
}

public Consumer<RoutingContext> createTenantResolverInterceptor(String tenantId) {
return new Consumer<RoutingContext>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.it.keycloak;

import jakarta.enterprise.event.Observes;
import jakarta.inject.Singleton;

import io.quarkus.oidc.SecurityEvent;

@Singleton
public class OidcEventObserver {

private volatile boolean oidcServerNotAvailable = false;

void observe(@Observes SecurityEvent event) {
if (event.getEventType() == SecurityEvent.Type.OIDC_SERVER_NOT_AVAILABLE) {
oidcServerNotAvailable = true;
}
}

boolean isOidcServerNotAvailable() {
return oidcServerNotAvailable;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.it.keycloak;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/oidc-event")
public class OidcEventResource {

private final OidcEventObserver oidcEventObserver;

public OidcEventResource(OidcEventObserver oidcEventObserver) {
this.oidcEventObserver = oidcEventObserver;
}

@GET
public boolean oidcServerUnavailable() {
return oidcEventObserver.isOidcServerNotAvailable();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,11 @@ public void testInvalidBearerToken() {
.header("WWW-Authenticate", equalTo("Bearer"));
}

@Test
public void testOidcEventFiredWhenServerNotAvailable() {
RestAssured.given().get("/oidc-event").then().statusCode(200).body(Matchers.is("true"));
}

private String getAccessToken(String userName, Set<String> groups) {
return getAccessToken(userName, groups, SignatureAlgorithm.RS256);
}
Expand Down

0 comments on commit 39a0e35

Please sign in to comment.