alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (JMXPluggableAuthenticator.java)

This example Java source code file (JMXPluggableAuthenticator.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

appconfigurationentry, authentication, classlogger, credentials, fileloginconfig, jmxcallbackhandler, jmxpluggableauthenticator, login_config_name, logincontext, loginexception, security, securityexception, string, subject, unsupportedcallbackexception, util

The JMXPluggableAuthenticator.java Java example source code

/*
 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.jmx.remote.security;

import java.io.IOException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.management.remote.JMXPrincipal;
import javax.management.remote.JMXAuthenticator;
import javax.security.auth.AuthPermission;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.sun.jmx.remote.util.ClassLogger;
import com.sun.jmx.remote.util.EnvHelp;

/**
 * <p>This class represents a
 * <a href="{@docRoot}/../guide/security/jaas/JAASRefGuide.html">JAAS
 * based implementation of the {@link JMXAuthenticator} interface.</p>
 *
 * <p>Authentication is performed by passing the supplied user's credentials
 * to one or more authentication mechanisms ({@link LoginModule}) for
 * verification. An authentication mechanism acquires the user's credentials
 * by calling {@link NameCallback} and/or {@link PasswordCallback}.
 * If authentication is successful then an authenticated {@link Subject}
 * filled in with a {@link Principal} is returned.  Authorization checks
 * will then be performed based on this <code>Subject.

* * <p>By default, a single file-based authentication mechanism * {@link FileLoginModule} is configured (<code>FileLoginConfig).

* * <p>To override the default configuration use the * <code>com.sun.management.jmxremote.login.config management property * described in the JRE/lib/management/management.properties file. * Set this property to the name of a JAAS configuration entry and ensure that * the entry is loaded by the installed {@link Configuration}. In addition, * ensure that the authentication mechanisms specified in the entry acquire * the user's credentials by calling {@link NameCallback} and * {@link PasswordCallback} and that they return a {@link Subject} filled-in * with a {@link Principal}, for those users that are successfully * authenticated.</p> */ public final class JMXPluggableAuthenticator implements JMXAuthenticator { /** * Creates an instance of <code>JMXPluggableAuthenticator * and initializes it with a {@link LoginContext}. * * @param env the environment containing configuration properties for the * authenticator. Can be null, which is equivalent to an empty * Map. * @exception SecurityException if the authentication mechanism cannot be * initialized. */ public JMXPluggableAuthenticator(Map<?, ?> env) { String loginConfigName = null; String passwordFile = null; if (env != null) { loginConfigName = (String) env.get(LOGIN_CONFIG_PROP); passwordFile = (String) env.get(PASSWORD_FILE_PROP); } try { if (loginConfigName != null) { // use the supplied JAAS login configuration loginContext = new LoginContext(loginConfigName, new JMXCallbackHandler()); } else { // use the default JAAS login configuration (file-based) SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission( new AuthPermission("createLoginContext." + LOGIN_CONFIG_NAME)); } final String pf = passwordFile; try { loginContext = AccessController.doPrivileged( new PrivilegedExceptionAction<LoginContext>() { public LoginContext run() throws LoginException { return new LoginContext( LOGIN_CONFIG_NAME, null, new JMXCallbackHandler(), new FileLoginConfig(pf)); } }); } catch (PrivilegedActionException pae) { throw (LoginException) pae.getException(); } } } catch (LoginException le) { authenticationFailure("authenticate", le); } catch (SecurityException se) { authenticationFailure("authenticate", se); } } /** * Authenticate the <code>MBeanServerConnection client * with the given client credentials. * * @param credentials the user-defined credentials to be passed in * to the server in order to authenticate the user before creating * the <code>MBeanServerConnection. This parameter must * be a two-element <code>String[] containing the client's * username and password in that order. * * @return the authenticated subject containing a * <code>JMXPrincipal(username). * * @exception SecurityException if the server cannot authenticate the user * with the provided credentials. */ public Subject authenticate(Object credentials) { // Verify that credentials is of type String[]. // if (!(credentials instanceof String[])) { // Special case for null so we get a more informative message if (credentials == null) authenticationFailure("authenticate", "Credentials required"); final String message = "Credentials should be String[] instead of " + credentials.getClass().getName(); authenticationFailure("authenticate", message); } // Verify that the array contains two elements. // final String[] aCredentials = (String[]) credentials; if (aCredentials.length != 2) { final String message = "Credentials should have 2 elements not " + aCredentials.length; authenticationFailure("authenticate", message); } // Verify that username exists and the associated // password matches the one supplied by the client. // username = aCredentials[0]; password = aCredentials[1]; if (username == null || password == null) { final String message = "Username or password is null"; authenticationFailure("authenticate", message); } // Perform authentication try { loginContext.login(); final Subject subject = loginContext.getSubject(); AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { subject.setReadOnly(); return null; } }); return subject; } catch (LoginException le) { authenticationFailure("authenticate", le); } return null; } private static void authenticationFailure(String method, String message) throws SecurityException { final String msg = "Authentication failed! " + message; final SecurityException e = new SecurityException(msg); logException(method, msg, e); throw e; } private static void authenticationFailure(String method, Exception exception) throws SecurityException { String msg; SecurityException se; if (exception instanceof SecurityException) { msg = exception.getMessage(); se = (SecurityException) exception; } else { msg = "Authentication failed! " + exception.getMessage(); final SecurityException e = new SecurityException(msg); EnvHelp.initCause(e, exception); se = e; } logException(method, msg, se); throw se; } private static void logException(String method, String message, Exception e) { if (logger.traceOn()) { logger.trace(method, message); } if (logger.debugOn()) { logger.debug(method, e); } } private LoginContext loginContext; private String username; private String password; private static final String LOGIN_CONFIG_PROP = "jmx.remote.x.login.config"; private static final String LOGIN_CONFIG_NAME = "JMXPluggableAuthenticator"; private static final String PASSWORD_FILE_PROP = "jmx.remote.x.password.file"; private static final ClassLogger logger = new ClassLogger("javax.management.remote.misc", LOGIN_CONFIG_NAME); /** * This callback handler supplies the username and password (which was * originally supplied by the JMX user) to the JAAS login module performing * the authentication. No interactive user prompting is required because the * credentials are already available to this class (via its enclosing class). */ private final class JMXCallbackHandler implements CallbackHandler { /** * Sets the username and password in the appropriate Callback object. */ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { ((NameCallback)callbacks[i]).setName(username); } else if (callbacks[i] instanceof PasswordCallback) { ((PasswordCallback)callbacks[i]) .setPassword(password.toCharArray()); } else { throw new UnsupportedCallbackException (callbacks[i], "Unrecognized Callback"); } } } } /** * This class defines the JAAS configuration for file-based authentication. * It is equivalent to the following textual configuration entry: * <pre> * JMXPluggableAuthenticator { * com.sun.jmx.remote.security.FileLoginModule required; * }; * </pre> */ private static class FileLoginConfig extends Configuration { // The JAAS configuration for file-based authentication private AppConfigurationEntry[] entries; // The classname of the login module for file-based authentication private static final String FILE_LOGIN_MODULE = FileLoginModule.class.getName(); // The option that identifies the password file to use private static final String PASSWORD_FILE_OPTION = "passwordFile"; /** * Creates an instance of <code>FileLoginConfig * * @param passwordFile A filepath that identifies the password file to use. * If null then the default password file is used. */ public FileLoginConfig(String passwordFile) { Map<String, String> options; if (passwordFile != null) { options = new HashMap<String, String>(1); options.put(PASSWORD_FILE_OPTION, passwordFile); } else { options = Collections.emptyMap(); } entries = new AppConfigurationEntry[] { new AppConfigurationEntry(FILE_LOGIN_MODULE, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; } /** * Gets the JAAS configuration for file-based authentication */ public AppConfigurationEntry[] getAppConfigurationEntry(String name) { return name.equals(LOGIN_CONFIG_NAME) ? entries : null; } /** * Refreshes the configuration. */ public void refresh() { // the configuration is fixed } } }

Other Java examples (source code examples)

Here is a short list of links related to this Java JMXPluggableAuthenticator.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.