All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory Maven / Gradle / Ivy

The newest version!
/*
 *   Copyright 2019 Red Hat, Inc, and individual contributors.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */
package io.smallrye.jwt.auth.principal;

import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ServiceLoader;

/**
 * The factory class that provides the token string to JWTCallerPrincipal parsing for a given implementation.
 */
public abstract class JWTCallerPrincipalFactory {
    private static volatile JWTCallerPrincipalFactory instance;

    /**
     * Obtain the JWTCallerPrincipalFactory that has been set or by using the ServiceLoader pattern.
     *
     * @return the factory instance
     * @see #setInstance(JWTCallerPrincipalFactory)
     */
    public static JWTCallerPrincipalFactory instance() {
        if (instance != null) {
            return instance;
        }

        ClassLoader cl = AccessController
                .doPrivileged((PrivilegedAction) () -> Thread.currentThread().getContextClassLoader());
        if (cl == null) {
            cl = JWTCallerPrincipalFactory.class.getClassLoader();
        }

        JWTCallerPrincipalFactory newInstance = loadSpi(cl);

        if (newInstance == null && cl != JWTCallerPrincipalFactory.class.getClassLoader()) {
            cl = JWTCallerPrincipalFactory.class.getClassLoader();
            newInstance = loadSpi(cl);
        }
        if (newInstance == null) {
            newInstance = new DefaultJWTCallerPrincipalFactory();
        }

        return newInstance;
    }

    /**
     * Look for a JWTCallerPrincipalFactory service implementation using the ServiceLoader.
     *
     * @param cl - the ClassLoader to pass into the {@link ServiceLoader#load(Class, ClassLoader)} method.
     * @return the JWTCallerPrincipalFactory if found, null otherwise
     */
    private static JWTCallerPrincipalFactory loadSpi(ClassLoader cl) {
        if (cl == null) {
            return null;
        }

        // start from the root CL and go back down to the TCCL
        JWTCallerPrincipalFactory instance = loadSpi(cl.getParent());

        if (instance == null) {
            ServiceLoader sl = ServiceLoader.load(JWTCallerPrincipalFactory.class, cl);
            URL u = cl.getResource("/META-INF/services/io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactory");
            PrincipalLogging.log.loadSpi(cl, u, sl);
            try {
                for (JWTCallerPrincipalFactory spi : sl) {
                    if (instance != null) {
                        PrincipalLogging.log.multipleJWTCallerPrincipalFactoryFound(spi.getClass().getName(),
                                instance.getClass().getName());
                        break;
                    }

                    PrincipalLogging.log.currentSpi(sl, spi);
                    instance = spi;
                }
            } catch (Exception e) {
                PrincipalLogging.log.failedToLocateJWTCallerPrincipalFactoryProvider(e);
            }
        }
        return instance;
    }

    /**
     * Set the instance. It is used by OSGi environment where service loader pattern is not supported.
     *
     * @param resolver the instance to use.
     */
    public static synchronized void setInstance(JWTCallerPrincipalFactory resolver) {
        instance = resolver;
    }

    /**
     * Parse the given bearer token string into a JWTCallerPrincipal instance.
     *
     * @param token - the bearer token provided for authorization
     * @param authContextInfo - context/configuration details
     * @return A JWTCallerPrincipal representation for the token.
     * @throws ParseException on parse or verification failure.
     */
    public abstract JWTCallerPrincipal parse(String token, JWTAuthContextInfo authContextInfo) throws ParseException;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy