geronimo-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bert_nor <c...@mail.ru>
Subject Re: Error at getting datasource from connector(container-managed-security)
Date Wed, 02 May 2007 14:10:09 GMT

Thanks for advice.


djencks wrote:
> 
> Probably this is a bug, although I'm surprised we haven't seen it  
> before.
> 
> Can you please outline your scenario a bit more?
> 
> - is this work done from a secured part of your application, so there  
> is a subject available?
> - do you want database access to be "secured" based on the default  
> user/password supplied in the connector plan, or do you want the  
> password credentials to be determined from the user in some way (such  
> as using the user/pw of the actual user to access the database).
> 
> 
Yes, I am using the user/pw of the actual user to access the database.


djencks wrote:
> 
> If you want the db credentials to be determined from the actual user,  
> then this is only a configuration problem in your app.  You need to  
> include a login module in your login configuration that will  
> construct the PasswordCredential for the connector framework to use.   
> However, AFAIK this hasn't been tested much for a long time and may  
> have broken.  You include the   
> CallerIdentityPasswordCredentialLoginModule and install it in the  
> login config using the PasswordCredentialLoginModuleWrapperGBean  
> instead of the regular LoginModuleGBean.   You can also write a  
> different LoginModule that can apply some mapping between the actual  
> user and database user.
> 
> thanks
> david jencks
> 

It works well. It's my new module. 

<gbean xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2"
		name="kdw_login_module"
	
class="org.apache.geronimo.connector.outbound.security.PasswordCredentialLoginModuleWrapper">
		<attribute name="loginModuleClass">
			ru.mev.j2report.system.security.KDWLoginModule
		</attribute>
		<attribute name="serverSide">true</attribute>
		<reference name="ManagedConnectionFactoryWrapper">
			<name>jdbc/OracleDataSourceTest</name>
		</reference>
		<attribute name="options">
			dataSourceName=jdbc/OracleDataSourceTest
			groupSelect=select role_code from kdw.w_user_roles
		</attribute>
		<attribute name="loginDomainName">kdw_realm</attribute>
	</gbean>
	<gbean xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2"
		name="kdw_login"
		class="org.apache.geronimo.security.jaas.JaasLoginModuleUse">
		<attribute name="controlFlag">REQUIRED</attribute>
		<reference name="LoginModule">
			<name>kdw_login_module</name>
		</reference>
	</gbean>
	<gbean xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2"
		name="kdw_realm"
		class="org.apache.geronimo.security.realm.GenericSecurityRealm">
		<attribute name="realmName">kdw_realm</attribute>
		<reference name="ServerInfo">
			<name>ServerInfo</name>
		</reference>
		<reference name="LoginService">
			<name>JaasLoginService</name>
		</reference>
		<reference name="LoginModuleConfiguration">
			<name>kdw_login</name>
		</reference>
	</gbean>

public class KDWLoginModule implements LoginModule {
	/**
	 * Logger for this class
	 */
	private static final Log logger = LogFactory.getLog(KDWLoginModule.class);

	public final static String DATABASE_POOL_NAME = "dataSourceName";

	public final static String GROUP_SELECT = "groupSelect";

	private JCAManagedConnectionFactory factory;

	private Subject subject;

	private CallbackHandler handler;

	private String cbUsername;

	private String cbPassword;

	private String groupSelect;

	private Set<Principal> groups;
	
	private ManagedConnectionFactory managedConnectionFactory ;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.security.auth.spi.LoginModule#abort()
	 */
	public boolean abort() throws LoginException {
		cbUsername = null;
        cbPassword = null;
        return true; 
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.security.auth.spi.LoginModule#commit()
	 */
	public boolean commit() throws LoginException {
		Set<Principal> principals = subject.getPrincipals();
		principals.addAll(groups);
		// from  CallerIdentityPasswordCredentialLoginModule
		PasswordCredential passwordCredential = new PasswordCredential(cbUsername,
cbPassword.toCharArray());
       
passwordCredential.setManagedConnectionFactory(managedConnectionFactory);
        subject.getPrivateCredentials().add(passwordCredential); 
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject,
	 *      javax.security.auth.callback.CallbackHandler, java.util.Map,
	 *      java.util.Map)
	 */
	public void initialize(Subject subject, CallbackHandler handler,
			Map<String, ?> sharedState, Map<String, ?> options) {
		this.subject = subject;
		this.handler = handler;
		this.groupSelect = (String) options.get(GROUP_SELECT);
		this.groups = new HashSet<Principal>();

		String dataSourceName = (String) options.get(DATABASE_POOL_NAME);
		if (dataSourceName == null) {
			return;
		}
		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 (Iterator<AbstractName> it = set.iterator(); it.hasNext();) {
			AbstractName name = it.next();
			if (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
				}
			}
		}
		managedConnectionFactory =(ManagedConnectionFactory)
options.get(org.apache.geronimo.connector.outbound.security.PasswordCredentialLoginModuleWrapper.MANAGED_CONNECTION_FACTORY_OPTION);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.security.auth.spi.LoginModule#login()
	 */
	public boolean login() throws LoginException {
		Callback[] callbacks = new Callback[2];

		callbacks[0] = new NameCallback("User name");
		callbacks[1] = new PasswordCallback("Password", false);
		try {
			handler.handle(callbacks);
		} catch (IOException ioe) {
			throw (LoginException) new LoginException().initCause(ioe);
		} catch (UnsupportedCallbackException uce) {
			throw (LoginException) new LoginException().initCause(uce);
		}
		assert callbacks.length == 2;
		cbUsername = ((NameCallback) callbacks[0]).getName();
		if (cbUsername == null || cbUsername.equals("")) {
			return false;
		}
		char[] provided = ((PasswordCallback) callbacks[1]).getPassword();
		cbPassword = provided == null ? null : new String(provided);

		Connection conn = null;
		if (factory != null) {
			DataSource ds = (DataSource) factory.getConnectionFactory();
			try {
				conn = ds.getConnection(cbUsername, cbPassword);
				//conn = ds.getConnection();
			} catch (Exception e) {
				throw new FailedLoginException(e.getMessage());
			}
		} else {
			throw new FailedLoginException(
					"Login is failed. The data source is null.");
		}

		Statement statement = null;
		ResultSet result = null;
		try {
			statement = conn.createStatement();
			result = statement.executeQuery(groupSelect);
			while (result.next()) {
				String role = result.getString(1);
				groups.add(new GeronimoGroupPrincipal(role));
			}
			result.close();
			statement.close();
		} catch (SQLException sqle) {
			throw (LoginException) new LoginException("SQL error")
					.initCause(sqle);
		} finally {
			...
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.security.auth.spi.LoginModule#logout()
	 */
	public boolean logout() throws LoginException {
		cbUsername = null;
        cbPassword = null;
        return true; 
	}
}


But I modified PasswordCredentialLoginModuleWrapper and
PasswordCredentialLoginModuleWrapperGBean classes:

- PasswordCredentialLoginModuleWrapper. The "options" are not accessible
(null) in the constructor.

   private ManagedConnectionFactory managedConnectionFactory;
    
    public PasswordCredentialLoginModuleWrapper(String loginModuleClass,
String objectName, boolean serverSide, boolean wrapPrincipals,
ManagedConnectionFactoryWrapper managedConnectionFactoryWrapper, ClassLoader
classLoader) {
        super(loginModuleClass, objectName, serverSide, wrapPrincipals,
classLoader);
        managedConnectionFactory =
managedConnectionFactoryWrapper.$getManagedConnectionFactory();
       //Properties options=getOptions();
        //options.put(MANAGED_CONNECTION_FACTORY_OPTION,
managedConnectionFactory);
    }

	@Override
	public void setOptions(Properties options) {
		super.setOptions(options);
		getOptions().put(MANAGED_CONNECTION_FACTORY_OPTION,
managedConnectionFactory);
	}
-PasswordCredentialLoginModuleWrapperGBean. The constructor with parameter
'ManagedConnectionFactoryWrapper' is not defined.

infoFactory.setConstructor(new String[]{"loginModuleClass", "objectName",
"serverSide", "wrapPrincipals","ManagedConnectionFactoryWrapper",
"classLoader"});

-- 
View this message in context: http://www.nabble.com/Error-at-getting-datasource-from-connector%28container-managed-security%29-tf3661217s134.html#a10286848
Sent from the Apache Geronimo - Users mailing list archive at Nabble.com.


Mime
View raw message