dev@glassfish.java.net

Glassfish connector

From: Mahv <emahaev_at_gmail.com>
Date: Tue, 11 Aug 2009 00:54:19 -0700 (PDT)

The implementation of Glassfish connector does not check the availability a
credential to access to resource of the current subject. For example this
credential may be set in custom LoginModule.

CustomLoginModule:

public boolean commit() throws LoginException {
  ResourcesUtil rutil = ResourcesUtil.createInstance();
  ConfigBean[][] beanss = beanss = rutil.getJdbcResources();
  // find pool name
  ...
  ConnectorRegistry connectorRegistry = ConnectorRegistry.getInstance();
  ManagedConnectionFactory mcf =
connectorRegistry.getManagedConnectionFactory(poolName);
  PasswordCredential passwordCredential = new PasswordCredential(_username,
_password.toCharArray());
  passwordCredential.setManagedConnectionFactory(mcf);
  getSubject().getPrivateCredentials().add(passwordCredential);
  ...
}

For this case I modified the ConnectionManagerImpl:

// added
private ResourcePrincipal
extractResourcePrincipalFromSubject(ManagedConnectionFactory mcf){
  SecurityContext securityContext = SecurityContext.getCurrent();
  Subject s = securityContext.getSubject();
  if (s != null) {
    Set<PasswordCredential> creds =
s.getPrivateCredentials(PasswordCredential.class);
    for (PasswordCredential passwordCredential : creds) {
      if (mcf.equals(passwordCredential.getManagedConnectionFactory())) {
        return new ResourcePrincipal(passwordCredential.getUserName(), new
String(passwordCredential
                                                        .getPassword()));
      }
    }
    return null;
}

public Object allocateConnection(ManagedConnectionFactory mcf,
                        ConnectionRequestInfo cxRequestInfo, String jndiNameToUse,
                        Object conn) throws ResourceException {
  ....
  if (ref == null) {
    _logger.log(Level.FINE, "poolmgr.no_resource_reference",jndiNameToUse);
    SecurityContext securityContext = SecurityContext.getCurrent();
    Subject s = securityContext.getSubject();

    ResourcePrincipal prin = extractResourcePrincipalFromSubject(mcf);

    if(prin==null){
      prin=defaultPrin;
    }
    return internalGetConnection(mcf, prin, cxRequestInfo,
                                        resourceShareable, jndiNameToUse, conn, true);
  }
  ....
  if (auth.equals(ref.APPLICATION_AUTHORIZATION)) {
    ...
  }else{
    ResourcePrincipal prin = null;
    Set principalSet = null;
    Principal callerPrincipal = null;
    SecurityContext securityContext = null;
    ConnectorRuntime connectorRuntime = ConnectorRuntime.getRuntime();
    if (connectorRuntime.isServer()
      && (securityContext = SecurityContext.getCurrent()) != null
      && (callerPrincipal = securityContext.getCallerPrincipal()) != null
      && (principalSet = securityContext.getPrincipalSet()) != null) {

      prin=extractResourcePrincipalFromSubject(mcf);
                
      if (prin == null) {
      AuthenticationService authService = connectorRuntime
                                .getAuthenticationService(rarName, poolName);
      if (authService != null) {
        prin = (ResourcePrincipal) authService.mapPrincipal(callerPrincipal,
principalSet);
      }
    }
  }
  ...
}

It works now in my project with Oracle FGA and EclipseLink. What do you
think about this?
-- 
View this message in context: http://www.nabble.com/Glassfish-connector-tp24913296p24913296.html
Sent from the java.net - glassfish dev mailing list archive at Nabble.com.