You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by oz...@apache.org on 2004/01/23 09:14:53 UTC
cvs commit: jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi SlideLoginModule.java SlideRole.java SlidePrincipal.java SlideGroup.java
ozeigermann 2004/01/23 00:14:53
Added: proposals/jaas/org/apache/slide/jaas/spi
SlideLoginModule.java SlideRole.java
SlidePrincipal.java SlideGroup.java
Log:
Added JAAS authentication contribution by Unico Hommes
Revision Changes Path
1.1 jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlideLoginModule.java
Index: SlideLoginModule.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlideLoginModule.java,v 1.1 2004/01/23 08:14:52 ozeigermann Exp $
* $Revision: 1.1 $
* $Date: 2004/01/23 08:14:52 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2004 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Slide", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.jaas.spi;
import java.io.IOException;
import java.security.Principal;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Map;
import javax.security.auth.Subject;
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.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.authenticate.SecurityToken;
import org.apache.slide.common.Domain;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.SlideException;
import org.apache.slide.common.SlideToken;
import org.apache.slide.common.SlideTokenImpl;
import org.apache.slide.content.Content;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.security.ACLSecurityImpl;
import org.apache.slide.security.Security;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.structure.SubjectNode;
/**
* JAAS LoginModule for authenticating against users in a Slide namespace.
*
* <p>
* The implementation assumes the ACLSecurityImpl is used.
* </p>
*
* Options include (to be specified in JAAS login configuration file):
* <ul>
* <li><code>namespace</code>: the namespace to load users from.
* Defaults to the default namespace from the Slide domain configuration.
* </li>
* </ul>
*
* @author <a href="mailto:unico@apache.org">Unico Hommes</a>
*/
public class SlideLoginModule implements LoginModule {
// Slide helpers
private Content m_content;
private Security m_security;
// Slide configuration
private String m_usersPath;
private String m_rolesPath;
// authentication state information
private boolean m_authenticated = false;
private Subject m_subject;
private Principal m_principal;
private Principal[] m_roles;
private Group m_group;
private boolean m_committed = false;
private CallbackHandler m_callbackHandler;
private Map m_sharedState;
public SlideLoginModule() {
}
/**
* Initialize this <code>LoginModule</code> with the specified
* configuration information.
*
* @param subject The <code>Subject</code> to be authenticated
* @param callbackHandler A <code>CallbackHandler</code> for communicating
* with the end user as necessary
* @param sharedState State information shared with other
* <code>LoginModule</code> instances
* @param options Configuration information for this specific
* <code>LoginModule</code> instance
*/
public void initialize(
Subject subject,
CallbackHandler callbackHandler,
Map sharedState,
Map options) {
m_subject = subject;
m_callbackHandler = callbackHandler;
m_sharedState = sharedState;
// namespace option
String namespace = (String) options.get("namespace");
if (namespace == null) {
namespace = Domain.getDefaultNamespace();
}
// access the namespace
NamespaceAccessToken nat = Domain.accessNamespace(new SecurityToken(this),namespace);
m_content = nat.getContentHelper();
m_security = nat.getSecurityHelper();
m_usersPath = nat.getNamespaceConfig().getUsersPath();
m_rolesPath = nat.getNamespaceConfig().getRolesPath();
}
/**
* Phase 1 of authenticating a <code>Subject</code>.
*
* @return <code>true</code> if the authentication succeeded, or
* <code>false</code> if this <code>LoginModule</code> should be ignored
*
* @exception LoginException if the authentication fails
*/
public boolean login() throws LoginException {
if (m_callbackHandler == null) {
throw new LoginException ("No callback handler");
}
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("Username: ");
callbacks[1] = new PasswordCallback("Password: ",false);
try {
// prompt for username and password
m_callbackHandler.handle(callbacks);
String username = ((NameCallback) callbacks[0]).getName();
char[] password = ((PasswordCallback) callbacks[1]).getPassword();
if (username == null) {
throw new LoginException("No user name entered");
}
if (password == null) {
throw new LoginException("No password entered");
}
// share username and password with other LoginModules
m_sharedState.put("javax.security.auth.login.name",username);
m_sharedState.put("javax.security.auth.login.password",password);
// use the users own credentials to retrieve its info
SlideToken slideToken = new SlideTokenImpl(new CredentialsToken(username));
// retrieve user object
SubjectNode userNode;
try {
userNode = (SubjectNode) m_security.getPrincipal(slideToken);
}
catch (ObjectNotFoundException e) {
final String msg = "No such user";
if (Domain.isDebugEnabled()) {
Domain.debug("[SlideLoginModule] - " + msg);
}
throw new LoginException(msg);
}
catch (SlideException e) {
final String msg = "Failure loading user object";
Domain.error("[SlideLoginModule] - " + msg,e);
throw new LoginException(msg);
}
m_principal = new SlidePrincipal(username);
m_group = new SlideGroup();
NodeRevisionDescriptors revisions = m_content.retrieve(slideToken, m_usersPath + "/" + username);
NodeRevisionDescriptor revision = m_content.retrieve(slideToken, revisions);
// get the password property
NodeProperty property = revision.getProperty("password", NodeProperty.SLIDE_NAMESPACE);
if (property != null) {
m_authenticated = new String(password).equals(property.getValue());
if (!m_authenticated) {
final String msg = "Authentication failed";
if (Domain.isDebugEnabled()) {
Domain.debug("[SlideLoginModule] - " + msg + " for user " + username
+ ": wrong password.");
}
throw new LoginException(msg);
}
else if (Domain.isDebugEnabled()) {
Domain.debug("[SlideLoginModule] - user " + username
+ " successfully authenticated");
}
// find the roles the user is a member of
ArrayList list = new ArrayList();
Enumeration roles = ((ACLSecurityImpl) m_security).
getGroupMembership(slideToken, userNode);
while (roles.hasMoreElements()) {
String role = ((String) roles.nextElement()).substring(m_rolesPath.length()+1);
if (Domain.isDebugEnabled()) {
Domain.debug("[SlideLoginModule] - adding role " + role
+ " for user " + username);
}
SlideRole slideRole = new SlideRole(role);
// apparently Jetty and Tomcat expect the roles to be
// at different locations:
// the Group is to satisfy Jetty, the list is to satisfy Tomcat
m_group.addMember(slideRole);
list.add(slideRole);
}
m_roles = (Principal[]) list.toArray(new Principal[list.size()]);
return true;
}
else {
final String msg = "User " + username + " doesn't have his password " +
"property set: can't authenticate.";
Domain.warn("[SlideLoginModule] - " + msg);
throw new LoginException(msg);
}
}
catch (IOException e) {
final String msg = "Failure during login()";
Domain.error("[SlideLoginModule] - " + msg,e);
throw new LoginException(msg);
}
catch (UnsupportedCallbackException e) {
final String msg = "Failure during login()";
Domain.error("[SlideLoginModule] - " + msg,e);
throw new LoginException(msg);
}
catch (SlideException e) {
final String msg = "Failure during login()";
Domain.error("[SlideLoginModule] - " + msg,e);
throw new LoginException(msg);
}
}
/**
* Phase 2 of authenticating a <code>Subject</code> when Phase 1
* was successful. This method is called if the <code>LoginContext</code>
* succeeded in the overall authentication chain.
*
* @return <code>true</code> if the authentication succeeded, or
* <code>false</code> if this <code>LoginModule</code> should be ignored
*
* @exception LoginException if the commit fails
*/
public boolean commit() throws LoginException {
if (m_authenticated) {
m_subject.getPrincipals().add(m_principal);
m_subject.getPrincipals().add(m_group);
for (int i = 0; i < m_roles.length; i++) {
m_subject.getPrincipals().add(m_roles[i]);
}
}
m_committed = true;
return m_authenticated;
}
/**
* Phase 2 of authenticating a <code>Subject</code> when Phase 1
* fails. This method is called if the <code>LoginContext</code>
* failed somewhere in the overall authentication chain.
*
* @return <code>true</code> if this method succeeded, or
* <code>false</code> if this <code>LoginModule</code> should be ignored
*
* @exception LoginException if the abort fails
*/
public boolean abort() throws LoginException {
m_principal = null;
m_group = null;
return m_authenticated;
}
/**
* Log out this user.
*
* @return <code>true</code> in all cases because this
* <code>LoginModule</code> should not be ignored.
*
* @exception LoginException if logging out failed
*/
public boolean logout() throws LoginException {
m_subject.getPrincipals().remove(m_principal);
m_subject.getPrincipals().remove(m_group);
m_committed = false;
m_principal = null;
m_group = null;
return true;
}
}
1.1 jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlideRole.java
Index: SlideRole.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlideRole.java,v 1.1 2004/01/23 08:14:52 ozeigermann Exp $
* $Revision: 1.1 $
* $Date: 2004/01/23 08:14:52 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2004 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Slide", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.jaas.spi;
public final class SlideRole extends SlidePrincipal {
public SlideRole(String name) {
super(name);
}
}
1.1 jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlidePrincipal.java
Index: SlidePrincipal.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlidePrincipal.java,v 1.1 2004/01/23 08:14:52 ozeigermann Exp $
* $Revision: 1.1 $
* $Date: 2004/01/23 08:14:52 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2004 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Slide", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.jaas.spi;
import java.security.Principal;
public class SlidePrincipal implements Principal {
private final String m_name;
public SlidePrincipal(String name) {
m_name = name;
}
public String getName() {
return m_name;
}
public int hashCode() {
return getName().hashCode();
}
public String toString() {
return getName();
}
public boolean equals(SlidePrincipal principal) {
return principal.getName().equals(getName());
}
}
1.1 jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlideGroup.java
Index: SlideGroup.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/proposals/jaas/org/apache/slide/jaas/spi/SlideGroup.java,v 1.1 2004/01/23 08:14:52 ozeigermann Exp $
* $Revision: 1.1 $
* $Date: 2004/01/23 08:14:52 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2004 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Slide", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.jaas.spi;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
public final class SlideGroup implements Group {
private final HashSet m_members = new HashSet();
public boolean addMember(Principal user) {
return m_members.add(user);
}
public boolean isMember(Principal member) {
return m_members.contains(member);
}
public Enumeration members() {
class MembersEnumeration implements Enumeration {
private Iterator m_iter;
public MembersEnumeration(Iterator iter) {
m_iter = iter;
}
public boolean hasMoreElements () {
return m_iter.hasNext();
}
public Object nextElement () {
return m_iter.next();
}
}
return new MembersEnumeration(m_members.iterator());
}
public boolean removeMember(Principal user) {
return m_members.remove(user);
}
public String getName() {
return "roles";
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org