authorizationopenid-connectinterceptorquarkusrequestfiltering

Quarkus Custom authorization interceptors


I have a Quarkus microservice doing authentication and authorization with Keycloak using quarkus-oidc and quarkus-keycloak-authorization extensions.

I need to additionally implement following two request interceptors/filters:

  1. A filter before any auth logic kicks in. This is to copy token from query param to header (required for web sockets). What should be the priority of this filter?
  2. A filter to have custom authorization logic. This should be executed after all authentication and keycloak authorization logic but just before API execution? What should be priority of this filter?

I tried putting @Priority(Interceptor.Priority.PLATFORM_BEFORE) and @Prematching also to my filter, but even this is being called after OIDC kicks in.

Also, is there any way to support extending quarkus oidc logic to include custom code?

I am unable to get the priority of oidc and keycloak-auth interceptors (knowing these could help me deciding the priority of my filters). Please help.


Solution

  • Got the answer from quarkus google groups.

    For #2, ContainerRequestFilter with any priority (should not be @Prematching) will serve the purpose.
    Other option is to have custom HttpSecurityPolicy. This would be called after authentication.

    package org.acme.security.keycloak.authorization;
    
    import javax.enterprise.context.ApplicationScoped;
    
    import org.jboss.logging.Logger;
    
    import io.quarkus.security.identity.SecurityIdentity;
    import io.smallrye.mutiny.Uni;
    import io.vertx.ext.web.RoutingContext;
    
    @ApplicationScoped
    public class SecurityHandler implements io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy
    {
        @Override
        public Uni<CheckResult> checkPermission(RoutingContext request, Uni<SecurityIdentity> identity, AuthorizationRequestContext requestContext)
        {
            Logger.getLogger(LoggingFilter.class).infof("================ custom permission");
            return Uni.createFrom().item(CheckResult.PERMIT);
        }
    
    }
    

    For #1, we can have Vertx @RouteFilter

    Sample filter:
    Just note the priority. Higher the priority, first it will get called.

    package org.acme.security.keycloak.authorization;
    
    import io.quarkus.vertx.web.RouteFilter;
    import io.vertx.ext.web.RoutingContext;
    
    public class WSAuthFilter
    {
        @RouteFilter(1000) 
         void myFilter(RoutingContext rc) {
             rc.request().headers().add("Authorization", rc.request().query());
             rc.next(); 
        }
    }