io.quarkiverse.renarde.util.RenardeJWTAuthMechanism Maven / Gradle / Ivy
The newest version!
package io.quarkiverse.renarde.util;
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.logging.Logger;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.quarkiverse.renarde.impl.RenardeConfigBean;
import io.quarkus.smallrye.jwt.runtime.auth.JWTAuthMechanism;
import io.quarkus.smallrye.jwt.runtime.auth.SmallRyeJwtConfig;
import io.quarkus.vertx.http.runtime.security.ChallengeData;
import io.smallrye.mutiny.Uni;
import io.vertx.core.http.Cookie;
import io.vertx.ext.web.RoutingContext;
/**
* This class replaces the original JWTAuthMechanism with a lower priority, so that other interactive auth
* such as WebAuthn, OIDC or Form get a chance to issue a redirect challenge, when this dumbass can only
* issue a 401, and since the auth mechanisms are in random order, we'd sometimes get a 401 and sometimes
* a proper redirect. It now issues a redirect, but stays in lower priority.
*/
@Priority(2000)
@ApplicationScoped
public class RenardeJWTAuthMechanism extends JWTAuthMechanism {
private static final Logger log = Logger.getLogger(RenardeJWTAuthMechanism.class);
@Inject
RenardeConfigBean config;
@ConfigProperty(name = "quarkus.renarde.auth.location-cookie")
String locationCookie;
// for CDI proxy
RenardeJWTAuthMechanism() {
this(null);
}
public RenardeJWTAuthMechanism(SmallRyeJwtConfig config) {
super(config);
}
@Override
public int getPriority() {
return -1000;
}
protected void storeInitialLocation(final RoutingContext exchange) {
exchange.response().addCookie(Cookie.cookie(locationCookie, exchange.request().absoluteURI())
.setPath("/").setSecure(exchange.request().isSSL()));
}
static Uni getRedirect(final RoutingContext exchange, final String location) {
String loc = exchange.request().scheme() + "://" + exchange.request().host() + location;
return Uni.createFrom().item(new ChallengeData(302, "Location", loc));
}
@Override
public Uni getChallenge(RoutingContext context) {
// always redirect to the login page, except when we have a special REST header
String authHeader = context.request().headers().get(HttpHeaderNames.AUTHORIZATION);
if (authHeader != null) {
return super.getChallenge(context);
}
if (context.request().uri().equals(config.getLoginPage())) {
log.errorf(
"Avoiding redirect loop, make sure that your endpoint annotated with @LoginPage is accessible without being authenticated: %s",
config.getLoginPage());
return super.getChallenge(context);
} else {
// we need to store the URL
storeInitialLocation(context);
return getRedirect(context, config.getLoginPage());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy