From 951251fdbaf1af0513691d609dc184d04a603ed6 Mon Sep 17 00:00:00 2001 From: Darran Lofthouse Date: Thu, 3 Nov 2011 12:55:01 +0000 Subject: [PATCH] [AS7-2490] Add username/password support when connecting to the server. These values can be specified in the configuration, if not specified the user will be prompted. --- README | 4 + .../common/AbstractServerConnection.java | 22 +++- .../common/ClientCallbackHandler.java | 107 ++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/jboss/as/plugin/deployment/common/ClientCallbackHandler.java diff --git a/README b/README index 9cd1031..3592a69 100644 --- a/README +++ b/README @@ -26,6 +26,10 @@ Configuration information can also be specified. The following configurations ar - The port the server is listening for administration requests on. The default is 9999. +- The username to connect as if prompted to authenticate by the server. + +- The password to use for authentication if prompted by the server. + - Whether or not for force the actions, e.g. if the deploy goal is executed redeploy if it already exists. The default is true. Goals: diff --git a/src/main/java/org/jboss/as/plugin/deployment/common/AbstractServerConnection.java b/src/main/java/org/jboss/as/plugin/deployment/common/AbstractServerConnection.java index 8e832ac..aeb812b 100644 --- a/src/main/java/org/jboss/as/plugin/deployment/common/AbstractServerConnection.java +++ b/src/main/java/org/jboss/as/plugin/deployment/common/AbstractServerConnection.java @@ -56,6 +56,25 @@ public abstract class AbstractServerConnection extends AbstractMojo { */ private int port; + /** + * Specifies the username to use if prompted to authenticate by the server. + * + * If no username is specified and the server requests authentication the user + * will be prompted to supply the username, + * + * @parameter + */ + private String username; + + /** + * Specifies the password to use if prompted to authenticate by the server. + * + * If no password is specified and the server requests authentication the user + * will be prompted to supply the password, + * + * @parameter + */ + private String password; /** * The hostname to deploy the archive to. The default is localhost. @@ -113,7 +132,8 @@ protected final ModelControllerClient client() throws UnknownHostException { if (client == null) { synchronized (this) { if (client == null) { - client = ModelControllerClient.Factory.create(hostAddress(), port()); + client = ModelControllerClient.Factory.create(hostAddress(), port(), + new ClientCallbackHandler(username, password)); } } } diff --git a/src/main/java/org/jboss/as/plugin/deployment/common/ClientCallbackHandler.java b/src/main/java/org/jboss/as/plugin/deployment/common/ClientCallbackHandler.java new file mode 100644 index 0000000..69ef73b --- /dev/null +++ b/src/main/java/org/jboss/as/plugin/deployment/common/ClientCallbackHandler.java @@ -0,0 +1,107 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2010, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.as.plugin.deployment.common; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.RealmCallback; +import javax.security.sasl.RealmChoiceCallback; +import java.io.IOException; + +/** + * A CallbackHandler implementation to supply the username and password if required when + * connecting to the server - if these are not available the user will be prompted to + * supply them. + * + * @author Darran Lofthouse + */ +class ClientCallbackHandler implements CallbackHandler { + + private boolean promptShown = false; + private String username; + private char[] password; + + ClientCallbackHandler(final String username, final String password) { + this.username = username; + if (password != null) { + this.password = password.toCharArray(); + } + } + + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + // Special case for anonymous authentication to avoid prompting user for their name. + if (callbacks.length == 1 && callbacks[0] instanceof NameCallback) { + ((NameCallback) callbacks[0]).setName("anonymous demo user"); + return; + } + + for (Callback current : callbacks) { + if (current instanceof RealmCallback) { + RealmCallback rcb = (RealmCallback) current; + String defaultText = rcb.getDefaultText(); + rcb.setText(defaultText); // For now just use the realm suggested. + + prompt(defaultText); + } else if (current instanceof RealmChoiceCallback) { + throw new UnsupportedCallbackException(current, "Realm choice not currently supported."); + } else if (current instanceof NameCallback) { + NameCallback ncb = (NameCallback) current; + String userName = obtainUsername("Username:"); + + ncb.setName(userName); + } else if (current instanceof PasswordCallback) { + PasswordCallback pcb = (PasswordCallback) current; + char[] password = obtainPassword("Password:"); + + pcb.setPassword(password); + } else { + throw new UnsupportedCallbackException(current); + } + } + } + + private void prompt(final String realm) { + if (promptShown == false) { + promptShown = true; + System.out.println("Authenticating against security realm: " + realm); + } + } + + private String obtainUsername(final String prompt) { + if (username == null) { + username = System.console().readLine(prompt); + } + return username; + } + + private char[] obtainPassword(final String prompt) { + if (password == null) { + password = System.console().readPassword(prompt); + } + + return password; + } + +}