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

org.glassfish.appclient.client.acc.AppClientContainerSecurityHelper Maven / Gradle / Ivy

There is a newer version: 8.0.0-JDK17-M9
Show newest version
/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.appclient.client.acc;

import com.sun.enterprise.container.common.spi.util.InjectionException;
import com.sun.enterprise.container.common.spi.util.InjectionManager;
import com.sun.enterprise.deployment.ApplicationClientDescriptor;
import com.sun.enterprise.security.appclient.integration.AppClientSecurityInfo;

import jakarta.inject.Inject;

import java.io.File;
import java.io.IOException;
import java.net.Authenticator;
import java.net.URI;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import javax.security.auth.callback.CallbackHandler;

import org.glassfish.appclient.client.acc.config.ClientCredential;
import org.glassfish.appclient.client.acc.config.MessageSecurityConfig;
import org.glassfish.appclient.client.acc.config.TargetServer;
import org.glassfish.hk2.api.PerLookup;
import org.jvnet.hk2.annotations.Service;

import static com.sun.enterprise.security.appclient.integration.AppClientSecurityInfo.CredentialType.USERNAME_PASSWORD;
import static java.util.Arrays.asList;
import static org.glassfish.appclient.client.acc.Util.writeTextToTempFile;

/**
 *
 * @author tjquinn
 */
@Service
@PerLookup
public class AppClientContainerSecurityHelper {

    private static final Logger logger = Logger.getLogger(AppClientContainerSecurityHelper.class.getName());

    @Inject
    private InjectionManager injectionManager;

    @Inject
    private AppClientSecurityInfo appClientSecurityInfo;

    private ClassLoader classLoader;

    void init(final TargetServer[] targetServers, final List msgSecConfigs, final Properties containerProperties,
            final ClientCredential clientCredential, final CallbackHandler callerSuppliedCallbackHandler, final ClassLoader classLoader,
            final ApplicationClientDescriptor acDesc, final boolean isTextAuth)
            throws ReflectiveOperationException, InjectionException, IOException {

        this.classLoader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader;

        initLoginConfig();
        CallbackHandler callbackHandler = initSecurity(callerSuppliedCallbackHandler, acDesc);

        appClientSecurityInfo.initializeSecurity(
            asList(targetServers),
            msgSecConfigs,
            callbackHandler,
            (clientCredential == null ? null : clientCredential.getUserName()),
            (clientCredential == null || clientCredential.getPassword() == null || clientCredential.getPassword().get() == null ? null
                        : clientCredential.getPassword().get()),
            false /* isJWS */,
            !isTextAuth /* useGUIAuth */);

        initHttpAuthenticator(USERNAME_PASSWORD);
    }

    private void initLoginConfig() throws IOException {
        /*
         * During Java Web Start launches, the appclientlogin.conf content is passed as a property. Store that content (if
         * present) into a local temporary file and use that during this app client launch.
         */
        final String appclientloginConfContent = System.getProperty("appclient.login.conf.content");
        URI configURI;
        if (appclientloginConfContent == null) {
            configURI = new File(System.getProperty("com.sun.aas.installRoot")).toURI().resolve("lib/appclient/appclientlogin.conf");
        } else {
            configURI = writeTextToTempFile(appclientloginConfContent, "appclientlogin", ".conf", false).toURI();
        }

        final File configFile = new File(configURI);

        /*
         * Ugly, but necessary. The Java com.sun.security.auth.login.ConfigFile class expects the
         * java.security.auth.login.config property value to be a URL, but one with NO encoding. That is, if the path to the
         * config file contains a blank then ConfigFile class expects the URL to contain a blank, not %20 for example. So, we
         * need to use the deprecated File.toURL() method to create such a URL.
         */
        System.setProperty("java.security.auth.login.config", configFile.toURL().toString());
    }

    /**
     * Sets the callback handler for future use.
     *
     * @param callbackHandler the callback handler to be used
     */
    private CallbackHandler initSecurity(final CallbackHandler callerSuppliedCallbackHandler, final ApplicationClientDescriptor applicationClientDescriptor)
            throws ReflectiveOperationException, InjectionException, ClassNotFoundException {

        /*
         * Choose a callback handler in this order: 1. callback handler class set by the program that created the
         * AppClientContainerBuilder. 2. callback handler class name set in the app client descriptor 3. null, in which case the
         * security layer provides a default callback handler
         *
         * Our default handler uses no injection, but a user-provided one might.
         */
        CallbackHandler callbackHandler = callerSuppliedCallbackHandler;
        if (callerSuppliedCallbackHandler == null) {
            final String descriptorCallbackHandlerClassName;
            if (applicationClientDescriptor != null && ((descriptorCallbackHandlerClassName = applicationClientDescriptor.getCallbackHandler()) != null)) {
                callbackHandler = newCallbackHandlerInstance(descriptorCallbackHandlerClassName, applicationClientDescriptor, classLoader);
            } else {
                callbackHandler = null;
            }
        }

        logger.config("Callback handler class = " + (callbackHandler == null ? "(default)" : callbackHandler.getClass().getName()));
        return callbackHandler;
    }

    private CallbackHandler newCallbackHandlerInstance(final String callbackHandlerClassName, final ApplicationClientDescriptor applicationClientDescriptor,
            final ClassLoader loader) throws ClassNotFoundException, ReflectiveOperationException, IllegalAccessException, InjectionException {

        @SuppressWarnings("unchecked")
        Class callbackHandlerClass = (Class) Class.forName(callbackHandlerClassName, true, loader);

        return newCallbackHandlerInstance(callbackHandlerClass, applicationClientDescriptor);
    }

    private CallbackHandler newCallbackHandlerInstance(final Class callbackHandlerClass,
            final ApplicationClientDescriptor applicationClientDescriptor) throws ReflectiveOperationException, IllegalAccessException, InjectionException {

        CallbackHandler userHandler = callbackHandlerClass.getDeclaredConstructor().newInstance();
        injectionManager.injectInstance(userHandler, applicationClientDescriptor);

        return userHandler;
    }

    /**
     * Clears the Client's current Security Context.
     */
    void clearClientSecurityContext() {
        appClientSecurityInfo.clearClientSecurityContext();
    }

    /**
     * Check if the Login attempt was cancelled.
     *
     * @return boolean indicating whether the login attempt was cancelled.
     */
    boolean isLoginCancelled() {
        return appClientSecurityInfo.isLoginCancelled();
    }

    private void initHttpAuthenticator(final AppClientSecurityInfo.CredentialType loginType) {
        Authenticator.setDefault(new HttpAuthenticator(appClientSecurityInfo, loginType));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy