You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by as...@apache.org on 2010/06/28 10:49:00 UTC

svn commit: r958505 - /geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/

Author: ashishjain
Date: Mon Jun 28 08:49:00 2010
New Revision: 958505

URL: http://svn.apache.org/viewvc?rev=958505&view=rev
Log:
GERONIMO-5197 Add generic header authentication modules for properties, ldap and sql.

Added:
    geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java   (with props)
    geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java   (with props)
    geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java   (with props)
    geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java   (with props)

Added: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java?rev=958505&view=auto
==============================================================================
--- geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java (added)
+++ geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java Mon Jun 28 08:49:00 2010
@@ -0,0 +1,440 @@
+package org.apache.geronimo.security.realm.providers;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.AuthenticationException;
+import javax.naming.CommunicationException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+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.geronimo.security.jaas.JaasLoginModuleUse;
+import org.apache.geronimo.security.jaas.WrappingLoginModule;
+
+public class GenericHttpHeaderLdapLoginModule extends GenericHttpHeaderLoginmodule implements LoginModule {
+    
+    private static Log log = LogFactory.getLog(GenericHttpHeaderLdapLoginModule.class);
+    
+    private final static String HEADER_NAMES="headerNames";
+    private final static String AUTHENTICATION_AUTHORITY="authenticationAuthority";
+    private static final String INITIAL_CONTEXT_FACTORY = "initialContextFactory";
+    private static final String CONNECTION_URL = "connectionURL";
+    private static final String CONNECTION_USERNAME = "connectionUsername";
+    private static final String CONNECTION_PASSWORD = "connectionPassword";
+    private static final String CONNECTION_PROTOCOL = "connectionProtocol";
+    private static final String AUTHENTICATION = "authentication";
+    private static final String USER_BASE = "userBase";
+    private static final String USER_SEARCH_MATCHING = "userSearchMatching";
+    private static final String USER_SEARCH_SUBTREE = "userSearchSubtree";
+    private static final String ROLE_BASE = "roleBase";
+    private static final String ROLE_NAME = "roleName";
+    private static final String ROLE_SEARCH_MATCHING = "roleSearchMatching";
+    private static final String ROLE_SEARCH_SUBTREE = "roleSearchSubtree";
+    private static final String USER_ROLE_NAME = "userRoleName";
+    public final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(INITIAL_CONTEXT_FACTORY, CONNECTION_URL,
+            CONNECTION_USERNAME,CONNECTION_PASSWORD, HEADER_NAMES, AUTHENTICATION_AUTHORITY, CONNECTION_PROTOCOL, AUTHENTICATION, USER_BASE,
+            USER_SEARCH_MATCHING, USER_SEARCH_SUBTREE, ROLE_BASE, ROLE_NAME, ROLE_SEARCH_MATCHING, ROLE_SEARCH_SUBTREE,
+            USER_ROLE_NAME));
+
+    private String initialContextFactory;
+    private String connectionURL;
+    private String connectionProtocol;
+    private String connectionUsername;
+    private String connectionPassword;
+    private String authentication;
+    private String userBase;
+    private String roleBase;
+    private String roleName;
+    private String userRoleName;
+
+    protected DirContext context = null;
+
+    private MessageFormat userSearchMatchingFormat;
+    private MessageFormat roleSearchMatchingFormat;
+    
+    private boolean userSearchSubtreeBool = false;
+    private boolean roleSearchSubtreeBool = false;
+
+    private boolean loginSucceeded;
+    private final Set<String> groups = new HashSet<String>();
+    private final Set<Principal> allPrincipals = new HashSet<Principal>();
+
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        for(Object option: options.keySet()) {
+            if(!supportedOptions.contains(option) && !JaasLoginModuleUse.supportedOptions.contains(option)
+                    && !WrappingLoginModule.supportedOptions.contains(option)) {
+                log.warn("Ignoring option: "+option+". Not supported.");
+            }
+        }
+        headerNames= (String)options.get(HEADER_NAMES);
+        authenticationAuthority=(String)options.get(AUTHENTICATION_AUTHORITY);
+        initialContextFactory = (String) options.get(INITIAL_CONTEXT_FACTORY);
+        connectionURL = (String) options.get(CONNECTION_URL);
+        connectionUsername = (String) options.get(CONNECTION_USERNAME);
+        connectionPassword = (String) options.get(CONNECTION_PASSWORD);
+        connectionProtocol = (String) options.get(CONNECTION_PROTOCOL);
+        authentication = (String) options.get(AUTHENTICATION);
+        userBase = (String) options.get(USER_BASE);
+        String userSearchMatching = (String) options.get(USER_SEARCH_MATCHING);
+        String userSearchSubtree = (String) options.get(USER_SEARCH_SUBTREE);
+        roleBase = (String) options.get(ROLE_BASE);
+        roleName = (String) options.get(ROLE_NAME);
+        String roleSearchMatching = (String) options.get(ROLE_SEARCH_MATCHING);
+        String roleSearchSubtree = (String) options.get(ROLE_SEARCH_SUBTREE);
+        userRoleName = (String) options.get(USER_ROLE_NAME);
+        userSearchMatchingFormat = new MessageFormat(userSearchMatching);
+        roleSearchMatchingFormat = new MessageFormat(roleSearchMatching);
+        userSearchSubtreeBool = Boolean.valueOf(userSearchSubtree);
+        roleSearchSubtreeBool = Boolean.valueOf(roleSearchSubtree);
+    }
+
+    /**
+     * This LoginModule is not to be ignored.  So, this method should never return false.
+     * @return true if authentication succeeds, or throw a LoginException such as FailedLoginException
+     *         if authentication fails
+     */
+    public boolean login() throws LoginException {
+        Map<String,String> headerMap=null;
+        loginSucceeded = false;
+        Callback[] callbacks = new Callback[1];
+        callbacks[0]= new RequestCallback();
+        try {
+            callbackHandler.handle(callbacks);
+        } catch (IOException ioe) {
+            throw (LoginException) new LoginException().initCause(ioe);
+        } catch (UnsupportedCallbackException uce) {
+            throw (LoginException) new LoginException().initCause(uce);
+        }
+        httpRequest  = ((RequestCallback) callbacks[0]).getRequest();
+        String []headers=headerNames.split(",");
+        try{
+        headerMap=matchHeaders(httpRequest, headers);
+        }
+        catch(HeaderMismatchException e){
+            throw (LoginException) new LoginException("Header Mistmatch error").initCause(e);
+        }
+        
+        if(headerMap.isEmpty()){
+            throw new FailedLoginException();
+        }
+        
+        if(authenticationAuthority.equalsIgnoreCase("Siteminder")){
+            HeaderHandler headerHandler= new SiteminderHeaderHandler();
+            username=headerHandler.getUser(headerMap);
+        }
+        else
+            if(authenticationAuthority.equalsIgnoreCase("Datapower"))
+            {
+                /*To be Done*/
+            }
+        if (username == null || username.equals("")) {
+            username = null;
+            throw new FailedLoginException();
+        }
+        
+        try {
+            boolean result = authenticate(username);
+            if (!result) {
+                throw new FailedLoginException();
+            }
+        } catch (LoginException e) {
+            // Clear out the private state
+            username = null;
+            groups.clear();
+            throw e;
+        } catch (Exception e) {
+            // Clear out the private state
+            username = null;
+            groups.clear();
+            throw (LoginException) new LoginException("LDAP Error").initCause(e);
+        }
+
+        loginSucceeded = true;
+        return loginSucceeded;
+    }
+
+    /*
+     * @exception LoginException if login succeeded but commit failed.
+     *
+     * @return true if login succeeded and commit succeeded, or false if login failed but commit succeeded.
+     */
+    public boolean commit() throws LoginException {
+        if(loginSucceeded) {
+            for(String group: groups) {
+                allPrincipals.add(new GeronimoGroupPrincipal(group));
+            }
+            subject.getPrincipals().addAll(allPrincipals);
+        }
+
+        // Clear out the private state
+        username = null;
+        groups.clear();
+
+        return loginSucceeded;
+    }
+
+    public boolean abort() throws LoginException {
+        if(loginSucceeded) {
+            // Clear out the private state
+            username = null;
+            groups.clear();
+            allPrincipals.clear();
+        }
+        return loginSucceeded;
+    }
+
+    public boolean logout() throws LoginException {
+        // Clear out the private state
+        loginSucceeded = false;
+        username = null;
+        groups.clear();
+        if(!subject.isReadOnly()) {
+            // Remove principals added by this LoginModule
+            subject.getPrincipals().removeAll(allPrincipals);
+        }
+        allPrincipals.clear();
+        return true;
+    }
+
+    protected void close(DirContext context) {
+        try {
+            context.close();
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    protected boolean authenticate(String username) throws Exception {
+        DirContext context = open();
+        try {
+
+            String filter = userSearchMatchingFormat.format(new String[]{username});
+            SearchControls constraints = new SearchControls();
+            if (userSearchSubtreeBool) {
+                constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            } else {
+                constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+            }
+
+            //setup attributes
+            String[] attribs;
+            if (userRoleName == null) {
+                attribs = new String[]{};
+            } else {
+                attribs = new String[]{userRoleName};
+            }
+            constraints.setReturningAttributes(attribs);
+
+
+            NamingEnumeration results = context.search(userBase, filter, constraints);
+
+            if (results == null || !results.hasMore()) {
+                log.error("No roles associated with user "+username);
+                loginSucceeded=false;
+                throw new FailedLoginException();
+            }
+
+            SearchResult result = (SearchResult) results.next();
+
+            if (results.hasMore()) {
+                //ignore for now
+            }
+            NameParser parser = context.getNameParser("");
+            Name contextName = parser.parse(context.getNameInNamespace());
+            Name baseName = parser.parse(userBase);
+            Name entryName = parser.parse(result.getName());
+            Name name = contextName.addAll(baseName);
+            name = name.addAll(entryName);
+            String dn = name.toString();
+
+            Attributes attrs = result.getAttributes();
+            if (attrs == null) {
+                return false;
+            }
+            ArrayList<String> roles = null;
+            if (userRoleName != null) {
+                roles = addAttributeValues(userRoleName, attrs, roles);
+            }
+            //check the credentials by binding to server
+          //  bindUser(context, dn);
+            //if authenticated add more roles
+            roles = getRoles(context, dn, username, roles);
+            for (String role : roles) {
+                groups.add(role);
+            }
+            if(groups.isEmpty()){
+                log.error("No roles associated with user "+username);
+                loginSucceeded=false;
+                throw new FailedLoginException();
+            }
+            else
+                loginSucceeded=true;
+            
+        } catch (CommunicationException e) {
+            close(context);
+            throw (LoginException) new FailedLoginException().initCause(e);
+        } catch (NamingException e) {
+            close(context);
+            throw (LoginException) new FailedLoginException().initCause(e);
+        }
+        return true;
+    }
+
+    protected ArrayList<String> getRoles(DirContext context, String dn, String username, ArrayList<String> list) throws NamingException {
+        if (list == null) {
+            list = new ArrayList<String>();
+        }
+        if (roleName == null || "".equals(roleName)) {
+            return list;
+        }
+        String filter = roleSearchMatchingFormat.format(new String[]{doRFC2254Encoding(dn), username});
+
+        SearchControls constraints = new SearchControls();
+        if (roleSearchSubtreeBool) {
+            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        } else {
+            constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+        }
+        NamingEnumeration results =
+                context.search(roleBase, filter, constraints);
+        while (results.hasMore()) {
+            SearchResult result = (SearchResult) results.next();
+            Attributes attrs = result.getAttributes();
+            if (attrs == null) {
+                continue;
+            }
+            list = addAttributeValues(roleName, attrs, list);
+        }
+        return list;
+    }
+
+
+    protected String doRFC2254Encoding(String inputString) {
+        StringBuffer buf = new StringBuffer(inputString.length());
+        for (int i = 0; i < inputString.length(); i++) {
+            char c = inputString.charAt(i);
+            switch (c) {
+                case'\\':
+                    buf.append("\\5c");
+                    break;
+                case'*':
+                    buf.append("\\2a");
+                    break;
+                case'(':
+                    buf.append("\\28");
+                    break;
+                case')':
+                    buf.append("\\29");
+                    break;
+                case'\0':
+                    buf.append("\\00");
+                    break;
+                default:
+                    buf.append(c);
+                    break;
+            }
+        }
+        return buf.toString();
+    }
+
+    protected void bindUser(DirContext context, String dn) throws NamingException, FailedLoginException {
+         
+        context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
+         try {
+            context.getAttributes("", null);
+        } catch (AuthenticationException e) {
+            log.debug("Authentication failed for dn=" + dn);
+            throw new FailedLoginException();
+        } finally {
+
+            if (connectionUsername != null) {
+                context.addToEnvironment(Context.SECURITY_PRINCIPAL,
+                        connectionUsername);
+            } else {
+                context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
+            }
+
+            if (connectionPassword != null) {
+                context.addToEnvironment(Context.SECURITY_CREDENTIALS,
+                        connectionPassword);
+            } else {
+                context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
+            }
+        }
+    }
+
+    private ArrayList<String> addAttributeValues(String attrId, Attributes attrs, ArrayList<String> values)
+            throws NamingException {
+
+        if (attrId == null || attrs == null) {
+            return values;
+        }
+        if (values == null) {
+            values = new ArrayList<String>();
+        }
+        Attribute attr = attrs.get(attrId);
+        if (attr == null) {
+            return (values);
+        }
+        NamingEnumeration e = attr.getAll();
+        while (e.hasMore()) {
+            String value = (String) e.next();
+            values.add(value);
+        }
+        return values;
+    }
+
+    protected DirContext open() throws NamingException {
+        if (context != null) {
+            return context;
+        }
+        try {
+            Hashtable<String, String> env = new Hashtable<String, String>();
+            env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
+            if (connectionUsername != null || !"".equals(connectionUsername)) {
+                env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
+            }
+            if (connectionPassword != null || !"".equals(connectionPassword)) {
+                env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
+            }
+            env.put(Context.SECURITY_PROTOCOL, connectionProtocol == null ? "" : connectionProtocol);
+            env.put(Context.PROVIDER_URL, connectionURL == null ? "" : connectionURL);
+            env.put(Context.SECURITY_AUTHENTICATION, authentication == null ? "" : authentication);
+            context = new InitialDirContext(env);
+
+        } catch (NamingException e) {
+            log.error(e);
+            throw e;
+        }
+        return context;
+    }
+}

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLdapLoginModule.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java?rev=958505&view=auto
==============================================================================
--- geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java (added)
+++ geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java Mon Jun 28 08:49:00 2010
@@ -0,0 +1,73 @@
+package org.apache.geronimo.security.realm.providers;
+
+import java.security.Principal;
+import java.util.HashMap;
+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.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory;
+/*
+ * Parent class for all the generic header login modules.
+ */
+public abstract class GenericHttpHeaderLoginmodule {
+    
+    private static Log log = LogFactory.getLog(GenericHttpHeaderLoginmodule.class);
+    
+    protected Subject subject;
+    protected String username;
+    protected String headerNames;
+    protected String authenticationAuthority;
+    protected JCAManagedConnectionFactory factory;
+    protected CallbackHandler callbackHandler;
+    protected boolean loginSucceeded;
+    protected HttpServletRequest httpRequest;
+    protected Set<Principal> allPrincipals = new HashSet<Principal>();
+    protected Set<String> groups = new HashSet<String>();
+    
+    public GenericHttpHeaderLoginmodule(){
+        
+    }
+    
+    protected void commitHelper(){
+        for(String group:groups){
+            allPrincipals.add(new GeronimoGroupPrincipal(group));
+        }
+        subject.getPrincipals().addAll(allPrincipals);
+        subject.getPublicCredentials().add(username);
+    }
+    
+    public void abortHelper(){
+        allPrincipals.clear();
+        groups.clear();
+    }
+    
+    public void logoutHelper(){
+        groups.clear();
+        if(!subject.isReadOnly()) {
+            // Remove principals added by this LoginModule
+            subject.getPrincipals().removeAll(allPrincipals);
+        }
+        allPrincipals.clear();
+    }
+    
+    public Map<String, String> matchHeaders(HttpServletRequest request, String[] headers) throws HeaderMismatchException{
+        Map<String,String> headerMap= new HashMap<String, String>();
+        for(String header:headers){
+            String headerValue=request.getHeader(header);
+            if(headerValue!=null){
+                headerMap.put(header, headerValue);
+            }
+            else
+                log.warn("An Unauthorized attempt has been made to access the protected resource from host "+request.getRemoteHost());
+        }
+        return headerMap;
+    }
+
+}

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderLoginmodule.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java?rev=958505&view=auto
==============================================================================
--- geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java (added)
+++ geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java Mon Jun 28 08:49:00 2010
@@ -0,0 +1,200 @@
+package org.apache.geronimo.security.realm.providers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+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.geronimo.common.GeronimoSecurityException;
+import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
+import org.apache.geronimo.security.jaas.WrappingLoginModule;
+import org.apache.geronimo.system.serverinfo.ServerInfo;
+
+public class GenericHttpHeaderPropertiesFileLoginModule extends GenericHttpHeaderLoginmodule implements LoginModule {
+    private  final static String GROUPS_URI = "groupsURI";
+    private final static String HEADER_NAMES="headerNames";
+    private final static String AUTHENTICATION_AUTHORITY="authenticationAuthority";
+    
+    public final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(GROUPS_URI, HEADER_NAMES, AUTHENTICATION_AUTHORITY));
+    private static Log log = LogFactory.getLog(PropertiesFileLoginModule.class);
+    final Map<String, Set<String>> roleUsersMap = new HashMap<String, Set<String>>();
+    
+    
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        headerNames= (String)options.get(HEADER_NAMES);
+        authenticationAuthority=(String)options.get(AUTHENTICATION_AUTHORITY);
+        
+        for(Object option: options.keySet()) {
+            if(!supportedOptions.contains(option) && !JaasLoginModuleUse.supportedOptions.contains(option)
+                    && !WrappingLoginModule.supportedOptions.contains(option)) {
+                log.warn("Ignoring option: "+option+". Not supported.");
+            }
+        }
+        try {
+            ServerInfo serverInfo = (ServerInfo) options.get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
+            final String groups = (String) options.get(GROUPS_URI);
+            
+            if (groups == null) {
+                throw new IllegalArgumentException(GROUPS_URI + " must be provided!");
+            }
+            URI groupsURI = new URI(groups);
+            loadProperties(serverInfo, groupsURI);
+        } catch (Exception e) {
+            log.error("Initialization failed", e);
+            throw new IllegalArgumentException("Unable to configure properties file login module: " + e.getMessage(),
+                    e);
+        }
+    }
+
+    public void loadProperties(ServerInfo serverInfo, URI groupURI) throws GeronimoSecurityException {
+        try {
+            URI groupFile = serverInfo.resolveServer(groupURI);
+            Properties temp = new Properties();
+            InputStream stream = groupFile.toURL().openStream();
+            temp.load(stream);
+            stream.close();
+
+            Enumeration e = temp.keys();
+            while (e.hasMoreElements()) {
+                String groupName = (String) e.nextElement();
+                String[] userList = ((String) temp.get(groupName)).split(",");
+
+                Set<String> userset = roleUsersMap.get(groupName);
+                if (userset == null) {
+                    userset = new HashSet<String>();
+                    roleUsersMap.put(groupName, userset);
+                }
+                for (String user : userList) {
+                    userset.add(user);
+                }
+            }
+
+        } catch (Exception e) {
+            log.error("Generic HTTP Header Properties File Login Module - data load failed", e);
+            throw new GeronimoSecurityException(e);
+        }
+    }
+
+    public boolean login() throws LoginException {
+        Map<String,String> headerMap=null;
+        loginSucceeded = false;
+        Callback[] callbacks = new Callback[1];
+        callbacks[0]= new RequestCallback();
+        try {
+            callbackHandler.handle(callbacks);
+        } catch (IOException ioe) {
+            throw (LoginException) new LoginException().initCause(ioe);
+        } catch (UnsupportedCallbackException uce) {
+            throw (LoginException) new LoginException().initCause(uce);
+        }
+        httpRequest  = ((RequestCallback) callbacks[0]).getRequest();
+        String []headers=headerNames.split(",");
+        try{
+        headerMap=matchHeaders(httpRequest, headers);
+        }
+        catch(HeaderMismatchException e){
+            throw (LoginException) new LoginException("Header Mistmatch error").initCause(e);
+        }
+        
+        if(headerMap.isEmpty()){
+            throw new FailedLoginException();
+        }
+        
+        if(authenticationAuthority.equalsIgnoreCase("Siteminder")){
+            HeaderHandler headerHandler= new SiteminderHeaderHandler();
+            username=headerHandler.getUser(headerMap);
+        }
+        else
+            if(authenticationAuthority.equalsIgnoreCase("Datapower"))
+            {
+                /*To be Done*/
+            }
+        if (username == null || username.equals("")) {
+            username = null;
+            throw new FailedLoginException();
+        }
+        
+        if(username!= null) {
+            for (Map.Entry<String, Set<String>> entry : roleUsersMap.entrySet()) {
+                String groupName = entry.getKey();
+                Set<String> users = entry.getValue();
+                for (String user : users) {
+                    if (username.equals(user)) {
+                        groups.add(groupName);
+                        break;
+                    }
+                }
+            }
+        }            
+        
+        if(groups.isEmpty()){
+            log.error("No roles associated with user "+username);
+            loginSucceeded=false;
+            throw new FailedLoginException();
+        }
+        else
+            loginSucceeded=true;
+            return loginSucceeded;
+    }
+
+    /*
+     * @exception LoginException if login succeeded but commit failed.
+     *
+     * @return true if login succeeded and commit succeeded, or false if login failed but commit succeeded.
+     */
+    public boolean commit() throws LoginException {        
+        if(loginSucceeded) {
+            if(username != null) {
+                super.commitHelper();
+            }
+        }
+
+        // Clear out the private state
+        username = null;
+        roleUsersMap.clear();
+        groups.clear();
+
+        return loginSucceeded;
+    }
+
+    public boolean abort() throws LoginException {
+        if(loginSucceeded) {
+            // Clear out the private state
+            username = null;
+            allPrincipals.clear();
+        }
+        return loginSucceeded;
+    }
+
+    public boolean logout() throws LoginException {
+        // Clear out the private state
+        loginSucceeded = false;
+        username = null;
+        if(!subject.isReadOnly()) {
+            // Remove principals added by this LoginModule
+            subject.getPrincipals().removeAll(allPrincipals);
+        }
+        allPrincipals.clear();
+        return true;
+    }    
+}

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderPropertiesFileLoginModule.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java?rev=958505&view=auto
==============================================================================
--- geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java (added)
+++ geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java Mon Jun 28 08:49:00 2010
@@ -0,0 +1,234 @@
+package org.apache.geronimo.security.realm.providers;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+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 javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gbean.AbstractName;
+import org.apache.geronimo.gbean.AbstractNameQuery;
+import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
+import org.apache.geronimo.kernel.GBeanNotFoundException;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.kernel.KernelRegistry;
+import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory;
+import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
+import org.apache.geronimo.security.jaas.WrappingLoginModule;
+
+
+public class GenericHttpHeaderSqlLoginmodule  extends GenericHttpHeaderLoginmodule implements LoginModule {
+    private static Log log = LogFactory.getLog(GenericHttpHeaderSqlLoginmodule.class);
+
+    private final static String GROUP_SELECT = "groupSelect";
+    private final static String USER = "jdbcUser";
+    private final static String DATABASE_POOL_NAME = "dataSourceName";
+    private final static String DATABASE_POOL_APP_NAME = "dataSourceApplication";
+    private final static String HEADER_NAMES="headerNames";
+    private final static String AUTHENTICATION_AUTHORITY="authenticationAuthority";
+    private final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(GROUP_SELECT, USER,
+            DATABASE_POOL_NAME, DATABASE_POOL_APP_NAME,HEADER_NAMES,AUTHENTICATION_AUTHORITY));
+    private  String groupSelect;
+    
+    public boolean abort() throws LoginException {
+        if(loginSucceeded) {
+            // Clear out the private state
+            username = null;
+            groups.clear();
+            allPrincipals.clear();
+        }
+        return loginSucceeded;
+    }
+
+    public boolean commit() throws LoginException {
+        if(loginSucceeded) {
+            if(username != null) {
+                super.commitHelper();
+            }
+        }
+
+        // Clear out the private state
+        username = null;
+        groups.clear();
+
+        return loginSucceeded;
+    }
+
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+            Map<String, ?> options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        for (Object option : options.keySet()) {
+            if (!supportedOptions.contains(option) && !JaasLoginModuleUse.supportedOptions.contains(option)
+                    && !WrappingLoginModule.supportedOptions.contains(option)) {
+                log.warn("Ignoring option: " + option + ". Not supported.");
+            }
+        }
+        headerNames= (String)options.get(HEADER_NAMES);
+        authenticationAuthority=(String)options.get(AUTHENTICATION_AUTHORITY);
+        groupSelect = (String) options.get(GROUP_SELECT);
+        String dataSourceName = (String) options.get(DATABASE_POOL_NAME);
+        if (dataSourceName != null) {
+            dataSourceName = dataSourceName.trim();
+            String dataSourceAppName = (String) options.get(DATABASE_POOL_APP_NAME);
+            if (dataSourceAppName == null || dataSourceAppName.trim().equals("")) {
+                dataSourceAppName = "null";
+            } else {
+                dataSourceAppName = dataSourceAppName.trim();
+            }
+            String kernelName = (String) options.get(JaasLoginModuleUse.KERNEL_NAME_LM_OPTION);
+            Kernel kernel = KernelRegistry.getKernel(kernelName);
+            Set<AbstractName> set = kernel.listGBeans(new AbstractNameQuery(JCAManagedConnectionFactory.class.getName()));
+            JCAManagedConnectionFactory factory;
+            for (AbstractName name : set) {
+                if (name.getName().get(NameFactory.J2EE_APPLICATION).equals(dataSourceAppName)
+                        && name.getName().get(NameFactory.J2EE_NAME).equals(dataSourceName)) {
+                    try {
+                        factory = (JCAManagedConnectionFactory) kernel.getGBean(name);
+                        String type = factory.getConnectionFactoryInterface();
+                        if (type.equals(DataSource.class.getName())) {
+                            this.factory = factory;
+                            break;
+                        }
+                    } catch (GBeanNotFoundException e) {
+                        // ignore... GBean was unregistered
+                    }
+                }
+            }
+        }
+    }
+
+    public boolean login() throws LoginException {
+        Map<String,String> headerMap=null;
+        loginSucceeded = false;
+        Connection conn=null;
+        ResultSet result=null;
+        PreparedStatement statement=null;
+        Callback[] callbacks = new Callback[1];
+        callbacks[0]= new RequestCallback();
+        try {
+            callbackHandler.handle(callbacks);
+        } catch (IOException ioe) {
+            throw (LoginException) new LoginException().initCause(ioe);
+        } catch (UnsupportedCallbackException uce) {
+            throw (LoginException) new LoginException().initCause(uce);
+        }
+        httpRequest  = ((RequestCallback) callbacks[0]).getRequest();
+        String []headers=headerNames.split(",");
+        try{
+        headerMap=matchHeaders(httpRequest, headers);
+        }
+        catch(HeaderMismatchException e){
+            throw (LoginException) new LoginException("Header Mistmatch error").initCause(e);
+        }
+        
+        if(headerMap.isEmpty()){
+            throw new FailedLoginException();
+        }
+        
+        if(authenticationAuthority.equalsIgnoreCase("Siteminder")){
+            HeaderHandler headerHandler= new SiteminderHeaderHandler();
+            username=headerHandler.getUser(headerMap);
+        }
+        else
+            if(authenticationAuthority.equalsIgnoreCase("Datapower"))
+            {
+                /*To be Done*/
+            }
+        if (username == null || username.equals("")) {
+            username = null;
+            throw new FailedLoginException();
+        }
+        
+        if (factory != null) {
+            DataSource ds;
+            try {
+                 ds = (DataSource) factory.getConnectionFactory();
+                 conn = ds.getConnection();
+            
+            try {
+            statement = conn.prepareStatement(groupSelect);
+            int count = countParameters(groupSelect);
+            for (int i = 0; i < count; i++) {
+                statement.setObject(i + 1, username);
+            }
+            result = statement.executeQuery();
+            while (result.next()) {
+                String userName = result.getString(1);
+                String groupName = result.getString(2);
+                if(userName.equals(username))
+                groups.add(groupName);
+                }
+            if(groups.isEmpty()){
+                log.error("No roles associated with user "+username);
+                loginSucceeded=false;
+                throw new FailedLoginException();
+            }
+            else
+                loginSucceeded=true;
+            }
+            finally{
+                result.close();
+                statement.close();
+                conn.close();
+            }
+            }
+              catch (LoginException e) {
+                // Clear out the private state
+                username = null;
+                groups.clear();
+                throw e;
+            } catch (SQLException sqle) {
+                // Clear out the private state
+                username = null;
+                groups.clear();
+                throw (LoginException) new LoginException("SQL error").initCause(sqle);
+            } catch (Exception e) {
+                // Clear out the private state
+                username = null;
+                groups.clear();
+                throw (LoginException) new LoginException("Could not access datasource").initCause(e);
+            }
+        }
+        
+        return loginSucceeded;
+    }
+
+    public boolean logout() throws LoginException {
+        loginSucceeded = false;
+        username = null;
+        groups.clear();
+        if(!subject.isReadOnly()) {
+            // Remove principals added by this LoginModule
+            subject.getPrincipals().removeAll(allPrincipals);
+        }
+        allPrincipals.clear();
+        return true;
+    }
+
+    private static int countParameters(String sql) {
+        int count = 0;
+        int pos = -1;
+        while ((pos = sql.indexOf('?', pos + 1)) != -1) {
+            ++count;
+        }
+        return count;
+    }
+
+}

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/branches/2.1/framework/modules/geronimo-security/src/main/java/org/apache/geronimo/security/realm/providers/GenericHttpHeaderSqlLoginmodule.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain