/* * Copyright 2001, 2002 Sun Microsystems, Inc. All Rights Reserved. * * This software is the proprietary information of Sun Microsystems, Inc. * Use is subject to license terms. */ package com.sun.wpe.jdbcrealm; import java.util.Properties; import java.util.Vector; import java.util.HashMap; import java.sql.Connection; import java.sql.Statement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Driver; import java.sql.DriverManager; import javax.sql.DataSource; import javax.naming.InitialContext; import com.sun.enterprise.security.acl.RoleMapper; import com.sun.enterprise.security.auth.realm.BadRealmException; import com.sun.enterprise.security.auth.realm.NoSuchUserException; import com.sun.enterprise.security.auth.realm.NoSuchRealmException; import com.sun.enterprise.security.auth.realm.InvalidOperationException; import com.iplanet.ias.security.RealmConfig; import com.iplanet.ias.security.auth.realm.IASRealm; /** * JDBCRealm for supporting RDBMS authentication. * *

This login module provides a sample implementation of a custom realm. * You may use this sample as a template for creating alternate custom * authentication realm implementations to suit your applications needs. * *

In order to plug in a realm into the server you need to * implement both a login module (see JDBCLoginModule for an example) * which performs the authentication and a realm (as shown by this * class) which is used to manage other realm operations. * *

A custom realm should implement the following methods: * *

* *

IASRealm and other classes and fields referenced in the sample * code should be treated as opaque undocumented interfaces. * */ final public class JDBCRealm extends IASRealm { public static final String AUTH_TYPE = "JDBCRealm"; private static DataSource _datasource = null; Properties _realmProperties = null; Vector _groups = new Vector(); HashMap _groupCache = new HashMap(); Vector _emptyVector; public JDBCRealm() { } /** * Initialize a realm. This method will be invoked once during server * startup. * * @param props Initialization parameters configured for this realm * in server.xml * @exception BadRealmException If the configuration parameters * identify a corrupt realm. * @exception NoSuchRealmException If the configuration parameters * specify a realm which doesn't exist. * */ protected void init(Properties props) throws BadRealmException, NoSuchRealmException { System.out.print("JDBCRealm Init ... "); _realmProperties = props; String jaasCtx = props.getProperty(IASRealm.JAAS_CONTEXT_PARAM); this.setProperty(IASRealm.JAAS_CONTEXT_PARAM, jaasCtx); _emptyVector = new Vector(); System.out.println("done!"); System.out.println(_realmProperties.toString()); } /** * Returns a short description of the kind of authentication which is * supported by this realm. * * @return Description of the kind of authentication that is directly * supported by this realm. */ public String getAuthType() { return AUTH_TYPE; } /** * Returns the names of all the groups that this user belongs to. * This method is called during authorization when role mapping * to groups is processed. An implementation of this method can * cache the results for a given user or determine the membership * dynamically on every request, as desired. * * @param username Name of the user in this realm whose group listing * is needed. * @return Enumeration of group names (strings). * @exception InvalidOperationException thrown if the realm does not * support this operation - e.g. Certificate realm does not support * this operation. */ public java.util.Enumeration getGroupNames (String username) throws InvalidOperationException, NoSuchUserException { System.out.println("looking up groups for ["+username+"]"); Vector groups = new Vector(); String uid = this.escape(username); String usertable = this.getRealmProperty(JDBCLoginModule.PARAMS_USERTABLE); String grptable = this.getRealmProperty(JDBCLoginModule.PARAMS_GRPTABLE); String usernamecol = this.getRealmProperty(JDBCLoginModule.PARAMS_USERNAMECOL); String usergroupcol = this.getRealmProperty(JDBCLoginModule.PARAMS_USERGROUPCOL); String sql = null; if(grptable != null) sql = "SELECT "+usergroupcol+" FROM "+grptable+" WHERE "+usernamecol+" = '"+uid+"'"; else sql = "SELECT "+usergroupcol+" FROM "+usertable+" WHERE "+usernamecol+" = '"+uid+"'"; try { Connection db = this.getConnection(); Statement stmt = db.createStatement(); ResultSet rs = stmt.executeQuery(sql); while(rs.next()) { groups.add(rs.getString(1)); } stmt.close(); db.close(); } catch(SQLException se) { System.out.println(sql); se.printStackTrace(); } for(int z=0; z < groups.size(); z++) System.out.println((String) groups.get(z)); return groups.elements(); } /** * Returns the property string for this realm defined in server.xml */ public String getRealmProperty(String name) { return _realmProperties.getProperty(name); } /** * Get a connection to the db. **/ protected Connection getConnection() throws SQLException { String ds = this.getRealmProperty(JDBCLoginModule.PARAMS_DBSOURCE); String driver = this.getRealmProperty(JDBCLoginModule.PARAMS_DBDRIVERNAME); String dburl = this.getRealmProperty(JDBCLoginModule.PARAMS_DBURL); if(_datasource == null && ds != null) { System.out.println("Initializing datasource "+ds); try { InitialContext ctx = new InitialContext(); _datasource = (DataSource) ctx.lookup(ds); } catch (Exception e) { e.printStackTrace(); } } else if(_datasource == null) { // we are not using a datasource, so do it manually try { Class.forName(driver); } catch(Exception e) { System.out.println("Couldn't load class ... "+driver); } Connection dbcon = DriverManager.getConnection(dburl); return (dbcon); } else { // Datasource already initialized ... Open a new connection Connection dbcon = _datasource.getConnection(); return (dbcon); } return null; } /** * Escapes single quote marks(') in a String * * i.e. "it's" becomes "it\'s" **/ protected String escape(String s) { if(s == null) return s; String retvalue = s; if ( s.indexOf ("'") != -1 ) { StringBuffer hold = new StringBuffer(); char c; for ( int i = 0; i < s.length(); i++ ) { if ( (c=s.charAt(i)) == '\'' ) hold.append ("''"); else hold.append(c); } retvalue = hold.toString(); } return retvalue; } }