[jboss-cvs] JBossAS SVN: r112405 - in projects/security/security-negotiation/branches/security-negotiation-2.0.x: jboss-negotiation-common/src/main/java/org/jboss/security/negotiation and 5 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Nov 2 16:58:36 EDT 2011
Author: mposolda
Date: 2011-11-02 16:58:35 -0400 (Wed, 02 Nov 2011)
New Revision: 112405
Added:
projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/Constants.java
projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/common/CommonLoginModule.java
Modified:
projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/pom.xml
projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-extras/src/main/java/org/jboss/security/negotiation/AdvancedLdapLoginModule.java
projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/pom.xml
projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java
projects/security/security-negotiation/branches/security-negotiation-2.0.x/parent/pom.xml
Log:
SECURITY-132 Traditional authentication in SPNEGOLoginModule (other needed things like new classes CommonLoginModule and Constants created as well)
Modified: projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/pom.xml
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/pom.xml 2011-11-02 19:39:46 UTC (rev 112404)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/pom.xml 2011-11-02 20:58:35 UTC (rev 112405)
@@ -38,14 +38,18 @@
<artifactId>jboss-common-core</artifactId>
</dependency>
<dependency>
- <groupId>jboss.web</groupId>
- <artifactId>jbossweb</artifactId>
+ <groupId>org.jboss.security</groupId>
+ <artifactId>jbosssx</artifactId>
</dependency>
<dependency>
<groupId>jboss.web</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<dependency>
+ <groupId>jboss.web</groupId>
+ <artifactId>jbossweb</artifactId>
+ </dependency>
+ <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
Added: projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/Constants.java
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/Constants.java (rev 0)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/Constants.java 2011-11-02 20:58:35 UTC (rev 112405)
@@ -0,0 +1,31 @@
+package org.jboss.security.negotiation;
+
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.Oid;
+
+public class Constants
+{
+ public static final Oid KERBEROS_V5;
+
+ public static final Oid KERBEROS_V5_LEGACY;
+
+ public static final Oid NTLM;
+
+ public static final Oid SPNEGO;
+
+ static
+ {
+ try
+ {
+ KERBEROS_V5 = new Oid("1.2.840.113554.1.2.2");
+ KERBEROS_V5_LEGACY = new Oid("1.2.840.48018.1.2.2");
+ SPNEGO = new Oid("1.3.6.1.5.5.2");
+ NTLM = new Oid("1.3.6.1.4.1.311.2.2.10");
+ }
+ catch (GSSException e)
+ {
+ throw new RuntimeException("Unable to initialise Oid", e);
+ }
+ }
+
+}
Added: projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/common/CommonLoginModule.java
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/common/CommonLoginModule.java (rev 0)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-common/src/main/java/org/jboss/security/negotiation/common/CommonLoginModule.java 2011-11-02 20:58:35 UTC (rev 112405)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, 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.security.negotiation.common;
+
+import java.security.Principal;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+
+import org.jboss.security.auth.spi.AbstractServerLoginModule;
+
+/**
+ * A base login module for the other login modules within
+ * JBoss Negotiation.
+ *
+ * @author darran.lofthouse at jboss.com
+ * @since 27th November 2010
+ */
+public abstract class CommonLoginModule extends AbstractServerLoginModule
+{
+
+ /*
+ * Module State
+ */
+ /** The login identity */
+ private Principal identity;
+
+ /** The proof of login identity */
+ private char[] credential;
+
+ @Override
+ protected Principal getIdentity()
+ {
+ return identity;
+ }
+
+ protected void setIdentity(final Principal identity)
+ {
+ this.identity = identity;
+ }
+
+ protected char[] getCredential()
+ {
+ return credential;
+ }
+
+ /**
+ * Either retrieve existing values based on useFirstPass or use
+ * CallBackHandler to obtain the values.
+ */
+ protected void processIdentityAndCredential() throws LoginException
+ {
+ if (super.login() == true)
+ {
+ Object username = sharedState.get("javax.security.auth.login.name");
+ if (username instanceof Principal)
+ identity = (Principal) username;
+ else
+ {
+ String name = username.toString();
+ try
+ {
+ identity = createIdentity(name);
+ }
+ catch (Exception e)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Failed to create principal", e);
+ throw new LoginException("Failed to create principal: " + e.getMessage());
+ }
+ }
+ // We have no further use for a credential so no need to retrieve it.
+ }
+ else
+ {
+ try
+ {
+ NameCallback nc = new NameCallback("User name: ", "guest");
+ PasswordCallback pc = new PasswordCallback("Password: ", false);
+ Callback[] callbacks =
+ {nc, pc};
+
+ callbackHandler.handle(callbacks);
+ String username = nc.getName();
+ identity = createIdentity(username);
+ credential = pc.getPassword();
+ pc.clearPassword();
+ }
+ catch (Exception e)
+ {
+ LoginException le = new LoginException("Unable to obtain username/credential");
+ le.initCause(e);
+ throw le;
+ }
+
+ }
+ }
+
+}
+
Modified: projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-extras/src/main/java/org/jboss/security/negotiation/AdvancedLdapLoginModule.java
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-extras/src/main/java/org/jboss/security/negotiation/AdvancedLdapLoginModule.java 2011-11-02 19:39:46 UTC (rev 112404)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-extras/src/main/java/org/jboss/security/negotiation/AdvancedLdapLoginModule.java 2011-11-02 20:58:35 UTC (rev 112405)
@@ -50,7 +50,7 @@
import javax.security.auth.login.LoginException;
import org.jboss.security.SimpleGroup;
-import org.jboss.security.auth.spi.AbstractServerLoginModule;
+import org.jboss.security.negotiation.common.CommonLoginModule;
import org.jboss.security.negotiation.prototype.DecodeAction;
/**
@@ -71,7 +71,7 @@
* @author darran.lofthouse at jboss.com
* @since 3rd July 2008
*/
-public class AdvancedLdapLoginModule extends AbstractServerLoginModule
+public class AdvancedLdapLoginModule extends CommonLoginModule
{
/*
@@ -176,12 +176,6 @@
/*
* Module State
*/
- /** The login identity */
- private Principal identity;
-
- /** The proof of login identity */
- private char[] credential;
-
private SimpleGroup userRoles = new SimpleGroup("Roles");
private Set<String> processedRoleDNs = new HashSet<String>();
@@ -293,12 +287,6 @@
}
@Override
- protected Principal getIdentity()
- {
- return identity;
- }
-
- @Override
protected Group[] getRoleSets() throws LoginException
{
Group[] roleSets =
@@ -325,7 +313,7 @@
}
catch (Exception e)
{
- LoginException le = new LoginException("Unabe to decode bindCredential");
+ LoginException le = new LoginException("Unable to decode bindCredential");
le.initCause(e);
throw le;
}
@@ -372,57 +360,6 @@
return Boolean.valueOf(super.loginOk);
}
- /**
- * Either retrieve existing values based on useFirstPass or use
- * CallBackHandler to obtain the values.
- */
- protected void processIdentityAndCredential() throws LoginException
- {
- if (super.login() == true)
- {
- Object username = sharedState.get("javax.security.auth.login.name");
- if (username instanceof Principal)
- identity = (Principal) username;
- else
- {
- String name = username.toString();
- try
- {
- identity = createIdentity(name);
- }
- catch (Exception e)
- {
- log.debug("Failed to create principal", e);
- throw new LoginException("Failed to create principal: " + e.getMessage());
- }
- }
- // We have no further use for a credential so no need to retrieve it.
- }
- else
- {
- try
- {
- NameCallback nc = new NameCallback("User name: ", "guest");
- PasswordCallback pc = new PasswordCallback("Password: ", false);
- Callback[] callbacks =
- {nc, pc};
-
- callbackHandler.handle(callbacks);
- String username = nc.getName();
- identity = createIdentity(username);
- credential = pc.getPassword();
- pc.clearPassword();
- }
- catch (Exception e)
- {
- LoginException le = new LoginException("Unable to obtain username/credential");
- le.initCause(e);
- throw le;
- }
-
- }
- }
-
protected LdapContext constructLdapContext(String dn, Object credential, String authentication)
throws LoginException
{
@@ -540,6 +477,7 @@
protected void authenticate(String userDN) throws LoginException
{
+ char[] credential = getCredential();
if (credential.length == 0)
{
if (allowEmptyPassword == false)
Modified: projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/pom.xml
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/pom.xml 2011-11-02 19:39:46 UTC (rev 112404)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/pom.xml 2011-11-02 20:58:35 UTC (rev 112405)
@@ -48,7 +48,11 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- </dependency>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.security</groupId>
+ <artifactId>jbosssx</artifactId>
+ </dependency>
</dependencies>
</project>
Modified: projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java 2011-11-02 19:39:46 UTC (rev 112404)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOLoginModule.java 2011-11-02 20:58:35 UTC (rev 112405)
@@ -22,12 +22,15 @@
*/
package org.jboss.security.negotiation.spnego;
+import static org.jboss.security.negotiation.Constants.KERBEROS_V5;
+
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.acl.Group;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
@@ -37,12 +40,11 @@
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
-import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.Oid;
import org.jboss.security.SimpleGroup;
-import org.jboss.security.auth.spi.AbstractServerLoginModule;
import org.jboss.security.negotiation.NegotiationMessage;
+import org.jboss.security.negotiation.common.CommonLoginModule;
import org.jboss.security.negotiation.common.NegotiationContext;
import org.jboss.security.negotiation.spnego.encoding.NegTokenInit;
import org.jboss.security.negotiation.spnego.encoding.NegTokenTarg;
@@ -55,36 +57,47 @@
* @author darran.lofthouse at jboss.com
* @version $Revision$
*/
-public class SPNEGOLoginModule extends AbstractServerLoginModule
+public class SPNEGOLoginModule extends CommonLoginModule
{
- private static final String SPNEGO = "SPNEGO";
+ /*
+ * Configuration Option Constants
+ */
+ // If true drop the @REALM from the identity.
private static final String REMOVE_REALM_FROM_PRINCIPAL = "removeRealmFromPrincipal";
- private static final Oid kerberos;
+ // The security domain to authenticate to obtain the servers identity.
+ private static final String SERVER_SECURITY_DOMAIN = "serverSecurityDomain";
+ // The security domain to delegate username/password authentication to.
+ private static final String USERNAME_PASSWORD_DOMAIN = "usernamePasswordDomain";
+
+ /*
+ * General Constants
+ */
+
+ private static final String SPNEGO = "SPNEGO";
+
+ private static final Oid kerberos = KERBEROS_V5;
+
+ /*
+ * Configuration Options
+ */
+
+ private boolean removeRealmFromPrincipal;
+
// TODO - Pick a name for a default domain?
private String serverSecurityDomain;
- private boolean removeRealmFromPrincipal;
+ private String usernamePasswordDomain;
+ /*
+ * Module State
+ */
+
private LoginContext serverLoginContext = null;
- private Principal identity = null;
-
- static
- {
- try
- {
- kerberos = new Oid("1.2.840.113554.1.2.2");
- }
- catch (GSSException e)
- {
- throw new RuntimeException("Unable to initialise Oid", e);
- }
- }
-
@Override
public void initialize(final Subject subject, final CallbackHandler callbackHandler, final Map sharedState,
final Map options)
@@ -92,19 +105,27 @@
super.initialize(subject, callbackHandler, sharedState, options);
String temp;
// Which security domain to authenticate the server.
- serverSecurityDomain = (String) options.get("serverSecurityDomain");
- log.debug("serverSecurityDomain=" + serverSecurityDomain);
+ serverSecurityDomain = (String) options.get(SERVER_SECURITY_DOMAIN);
+ // Which security domain to delegate username/password authentication to.
+ usernamePasswordDomain = (String) options.get(USERNAME_PASSWORD_DOMAIN);
temp = (String) options.get(REMOVE_REALM_FROM_PRINCIPAL);
removeRealmFromPrincipal = Boolean.valueOf(temp);
if (removeRealmFromPrincipal == false && principalClassName == null)
{
principalClassName = KerberosPrincipal.class.getName();
}
+ if (log.isDebugEnabled())
+ {
+ log.debug("removeRealmFromPrincipal=" + removeRealmFromPrincipal);
+ log.debug("serverSecurityDomain=" + serverSecurityDomain);
+ log.debug("usernamePasswordDomain=" + usernamePasswordDomain);
+ }
}
@Override
public boolean login() throws LoginException
{
+ boolean TRACE = log.isTraceEnabled();
if (super.login() == true)
{
log.debug("super.login()==true");
@@ -113,7 +134,94 @@
super.loginOk = false;
+ Object result = innerLogin();
+
+ if (TRACE)
+ log.trace("Result - " + result);
+
+ if (result instanceof Boolean)
+ {
+ if (Boolean.TRUE.equals(result))
+ {
+ super.loginOk = true;
+ if (getUseFirstPass() == true)
+ {
+ Principal identity = getIdentity();
+ String userName = identity.getName();
+ if (log.isDebugEnabled())
+ log.debug("Storing username '" + userName + "' and empty password");
+ // Add the username and a null password to the shared state map
+ sharedState.put("javax.security.auth.login.name", identity);
+ sharedState.put("javax.security.auth.login.password", "");
+ }
+ }
+ }
+ else if (result instanceof Exception)
+ {
+ Exception e = (Exception) result;
+ log.error("Unable to authenticate", e);
+ throw new LoginException("Unable to authenticate - " + e.getMessage());
+ }
+
+ if (TRACE)
+ log.trace("super.loginOk " + super.loginOk);
+ if (super.loginOk == true)
+ {
+ return true;
+ }
+ else
+ {
+ throw new LoginException("Continuation Required.");
+ }
+
+ }
+
+ protected Object innerLogin() throws LoginException
+ {
NegotiationContext negotiationContext = NegotiationContext.getCurrentNegotiationContext();
+
+ if (negotiationContext == null)
+ {
+ if (usernamePasswordDomain == null)
+ {
+ throw new LoginException("No NegotiationContext and no usernamePasswordDomain defined.");
+ }
+
+ return usernamePasswordLogin();
+ }
+ else
+ {
+ return spnegoLogin(negotiationContext);
+ }
+
+ }
+
+ private Object usernamePasswordLogin() throws LoginException
+ {
+ log.debug("Falling back to username/password authentication");
+
+ LoginContext lc = new LoginContext(usernamePasswordDomain, callbackHandler);
+ lc.login();
+
+ Subject userSubject = lc.getSubject();
+ Set principals = userSubject.getPrincipals();
+ if (principals.isEmpty())
+ {
+ throw new LoginException("No principal returned after login.");
+ }
+ else if (principals.size() > 1)
+ {
+ log.warn("Multiple principals returned, using first principal in set.");
+ }
+
+ Principal identity = (Principal) principals.iterator().next();
+ setIdentity(identity);
+
+ return Boolean.TRUE;
+ }
+
+ private Object spnegoLogin(NegotiationContext negotiationContext) throws LoginException
+ {
NegotiationMessage requestMessage = negotiationContext.getRequestMessage();
if (requestMessage instanceof SPNEGOMessage == false)
{
@@ -128,30 +236,7 @@
AcceptSecContext action = new AcceptSecContext(negotiationContext);
Object result = Subject.doAs(server, action);
- log.trace("Result - " + result);
-
- if (result instanceof Boolean)
- {
- if (Boolean.TRUE.equals(result))
- {
- super.loginOk = true;
- if (getUseFirstPass() == true)
- {
- String userName = identity.getName();
- log.debug("Storing username '" + userName + "' and empty password");
- // Add the username and a null password to the shared state map
- sharedState.put("javax.security.auth.login.name", identity);
- sharedState.put("javax.security.auth.login.password", "");
- }
- }
- }
- else if (result instanceof Exception)
- {
- Exception e = (Exception) result;
- log.error("Unable to authenticate", e);
- throw new LoginException("Unable to authenticate - " + e.getMessage());
- }
-
+ return result;
}
finally
{
@@ -162,25 +247,10 @@
}
}
- log.trace("super.loginOk " + super.loginOk);
- if (super.loginOk == true)
- {
- return true;
- }
- else
- {
- throw new LoginException("Continuation Required.");
- }
-
}
+
@Override
- protected Principal getIdentity()
- {
- return identity;
- }
-
- @Override
protected Principal createIdentity(final String username) throws Exception
{
if (removeRealmFromPrincipal)
@@ -304,7 +374,7 @@
log.warn("Authentication was performed despite already being authenticated!");
// TODO - Refactor to only do this once.
- identity = new KerberosPrincipal(gssContext.getSrcName().toString());
+ setIdentity(new KerberosPrincipal(gssContext.getSrcName().toString()));
log.debug("context.getCredDelegState() = " + gssContext.getCredDelegState());
log.debug("context.getMutualAuthState() = " + gssContext.getMutualAuthState());
@@ -332,11 +402,11 @@
}
else
{
- identity = createIdentity(gssContext.getSrcName().toString());
+ setIdentity(createIdentity(gssContext.getSrcName().toString()));
log.debug("context.getCredDelegState() = " + gssContext.getCredDelegState());
log.debug("context.getMutualAuthState() = " + gssContext.getMutualAuthState());
- log.debug("context.getSrcName() = " + gssContext.getSrcName().toString());
+ log.debug("context.getSrcName() = " + gssContext.getSrcName().toString());
// TODO - Get these two in synch - maybe isAuthenticated based on an authentication method been set?
negotiationContext.setAuthenticationMethod(SPNEGO);
Modified: projects/security/security-negotiation/branches/security-negotiation-2.0.x/parent/pom.xml
===================================================================
--- projects/security/security-negotiation/branches/security-negotiation-2.0.x/parent/pom.xml 2011-11-02 19:39:46 UTC (rev 112404)
+++ projects/security/security-negotiation/branches/security-negotiation-2.0.x/parent/pom.xml 2011-11-02 20:58:35 UTC (rev 112405)
@@ -20,10 +20,12 @@
</scm>
<properties>
<version.jboss-web>2.1.3.GA</version.jboss-web>
- <version.log4j.log4j>1.2.14</version.log4j.log4j>
+ <version.log4j.log4j>1.2.14</version.log4j.log4j>
+ <version.jbosssx>2.0.3.SP1</version.jbosssx>
<version.org.jboss.jboss-common-core>2.2.14.GA</version.org.jboss.jboss-common-core>
<version.org.jboss.jbossas.jboss-as-security>5.1.0.GA</version.org.jboss.jbossas.jboss-as-security>
<version.junit>3.8.1</version.junit>
+ <version.securityspi>2.0.2.SP1</version.securityspi>
</properties>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
@@ -148,6 +150,16 @@
<artifactId>junit</artifactId>
<version>${version.junit}</version>
</dependency>
+ <dependency>
+ <groupId>org.jboss.security</groupId>
+ <artifactId>jbosssx</artifactId>
+ <version>${version.jbosssx}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.security</groupId>
+ <artifactId>jboss-security-spi</artifactId>
+ <version>${version.securityspi}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
More information about the jboss-cvs-commits
mailing list