Index: jaas/modules/src/main/java/org/apache/karaf/jaas/modules/osgi/OsgiConfigLoginModule.java =================================================================== --- jaas/modules/src/main/java/org/apache/karaf/jaas/modules/osgi/OsgiConfigLoginModule.java (revision 990101) +++ jaas/modules/src/main/java/org/apache/karaf/jaas/modules/osgi/OsgiConfigLoginModule.java (working copy) @@ -31,27 +31,19 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; +import org.apache.karaf.jaas.modules.AbstractKarafLoginModule; import org.apache.karaf.jaas.modules.RolePrincipal; import org.apache.karaf.jaas.modules.UserPrincipal; import org.osgi.service.cm.Configuration; -public class OsgiConfigLoginModule implements LoginModule { +public class OsgiConfigLoginModule extends AbstractKarafLoginModule { public static final String PID = "pid"; public static final String USER_PREFIX = "user."; - private Subject subject; - private CallbackHandler callbackHandler; - private Map options; - - private Set principals; - public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { - this.subject = subject; - this.callbackHandler = callbackHandler; - this.options = options; + super.initialize(subject, callbackHandler, options); } public boolean login() throws LoginException { @@ -103,10 +95,6 @@ } } - public boolean commit() throws LoginException { - subject.getPrincipals().addAll(principals); - return true; - } public boolean abort() throws LoginException { subject = null; Index: jaas/modules/src/main/java/org/apache/karaf/jaas/modules/RolePolicy.java =================================================================== --- jaas/modules/src/main/java/org/apache/karaf/jaas/modules/RolePolicy.java (revision 0) +++ jaas/modules/src/main/java/org/apache/karaf/jaas/modules/RolePolicy.java (revision 0) @@ -0,0 +1,82 @@ +/* + * Copyright 2010 iocanel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.karaf.jaas.modules; + +import java.security.Principal; +import java.security.acl.Group; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.security.auth.Subject; + +/** + * + * @author iocanel + */ +public enum RolePolicy { + + PREFIXED_ROLES("prefix") { + public void handleRoles(Subject subject,Set principals,String discriminator) { + for(Principal p:principals) { + if(p instanceof RolePrincipal){ + RolePrincipal rolePrincipal = new RolePrincipal(discriminator+p.getName()); + subject.getPrincipals().add(rolePrincipal); + } else { + subject.getPrincipals().add(p); + } + } + } + }, + GROUP_ROLES("group") { + public void handleRoles(Subject subject,Set principals,String discriminator) { + Group group = new GroupPrincipal(discriminator); + for(Principal p:principals) { + if(p instanceof RolePrincipal) { + group.addMember(p); + } else { + subject.getPrincipals().add(p); + } + } + subject.getPrincipals().add(group); + } + }; + + private String value; + + private static final Map policies = new HashMap(); + + static { + for (RolePolicy s : EnumSet.allOf(RolePolicy.class)) { + policies.put(s.getValue(), s); + } + } + + private RolePolicy(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + public static RolePolicy getPolicy(String code) { + return policies.get(code); + } + + public abstract void handleRoles(Subject subject,Set principals,String discriminator); +} Index: jaas/modules/src/main/java/org/apache/karaf/jaas/modules/AbstractKarafLoginModule.java =================================================================== --- jaas/modules/src/main/java/org/apache/karaf/jaas/modules/AbstractKarafLoginModule.java (revision 0) +++ jaas/modules/src/main/java/org/apache/karaf/jaas/modules/AbstractKarafLoginModule.java (revision 0) @@ -0,0 +1,64 @@ +/* + * Copyright 2010 iocanel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ +package org.apache.karaf.jaas.modules; + +import java.security.Principal; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + + +/** + * + * @author iocanel + */ +public abstract class AbstractKarafLoginModule implements LoginModule { + + protected Set principals = new HashSet(); + protected Subject subject; + protected String user; + protected CallbackHandler callbackHandler; + protected boolean debug; + protected Map options; + + protected String rolePolicy; + protected String roleDiscriminator; + + public boolean commit() throws LoginException { + RolePolicy policy = RolePolicy.getPolicy(rolePolicy); + if(policy != null && roleDiscriminator != null) { + policy.handleRoles(subject, principals, roleDiscriminator); + } else subject.getPrincipals().addAll(principals); + return true; + } + + protected void clear() { + user = null; + } + + public void initialize(Subject sub, CallbackHandler handler, Map options) { + this.subject = sub; + this.callbackHandler = handler; + rolePolicy = (String) options.get("rolePolicy"); + roleDiscriminator = (String) options.get("roleDisciriminator"); + debug = "true".equalsIgnoreCase((String) options.get("debug")); + } +} Index: jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesLoginModule.java =================================================================== --- jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesLoginModule.java (revision 990101) +++ jaas/modules/src/main/java/org/apache/karaf/jaas/modules/properties/PropertiesLoginModule.java (working copy) @@ -22,7 +22,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Properties; -import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; @@ -32,10 +31,10 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.karaf.jaas.modules.AbstractKarafLoginModule; import org.apache.karaf.jaas.modules.RolePrincipal; import org.apache.karaf.jaas.modules.UserPrincipal; @@ -43,23 +42,17 @@ * JAAS Login module for user / password, based on two properties files. * */ -public class PropertiesLoginModule implements LoginModule { +public class PropertiesLoginModule extends AbstractKarafLoginModule { private static final String USER_FILE = "users"; private static final Log LOG = LogFactory.getLog(PropertiesLoginModule.class); - private Subject subject; - private CallbackHandler callbackHandler; - private boolean debug; + private String usersFile; - private String user; - private Set principals = new HashSet(); + @Override public void initialize(Subject sub, CallbackHandler handler, Map sharedState, Map options) { - this.subject = sub; - this.callbackHandler = handler; - - debug = "true".equalsIgnoreCase((String) options.get("debug")); + super.initialize(sub,handler,options); usersFile = (String) options.get(USER_FILE) + ""; if (debug) { @@ -122,15 +115,6 @@ return true; } - public boolean commit() throws LoginException { - subject.getPrincipals().addAll(principals); - clear(); - if (debug) { - LOG.debug("commit"); - } - return true; - } - public boolean abort() throws LoginException { clear(); if (debug) { @@ -147,8 +131,4 @@ } return true; } - - private void clear() { - user = null; - } } Index: jaas/modules/src/main/java/org/apache/karaf/jaas/modules/GroupPrincipal.java =================================================================== --- jaas/modules/src/main/java/org/apache/karaf/jaas/modules/GroupPrincipal.java (revision 0) +++ jaas/modules/src/main/java/org/apache/karaf/jaas/modules/GroupPrincipal.java (revision 0) @@ -0,0 +1,59 @@ +/* + * Copyright 2010 iocanel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.karaf.jaas.modules; + +import java.security.Principal; +import java.security.acl.Group; +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * + * @author iocanel + */ +public class GroupPrincipal implements Group { + + private String name; + private Hashtable members = new Hashtable(); + + public GroupPrincipal(String name) { + this.name = name; + } + + public boolean addMember(Principal user) { + members.put(user.getName(), user); + return true; + } + + public boolean removeMember(Principal user) { + members.remove(user.getName()); + return true; + } + + public boolean isMember(Principal member) { + return members.contains(member.getName()); + } + + public Enumeration members() { + return members.elements(); + } + + public String getName() { + return name; + } +}