Skip to main content

GF Bug? Getting empty credentials in JCA Adapter

Please note these forums are being decommissioned and use the new and improved forums at
4 replies [Last post]
Joined: 2010-07-07

I've created a JCA adapter. I'm receiving blank credentials howerver in my getConnection method in my ManagedConnection class. What's strange is this works in WebSphere (never thought I'd encounter _that_ scenario).

In the Glassfish Console, I have a connector work map defined:

	princiapls: *
backend username: backendUser
backend password: topSecret

Here's my getConnection method:

	public Object getConnection(Subject subject, ConnectionRequestInfo cxRequestInfo)
throws ResourceException {

String operatorId = null;
String operatorPassword = null;

for (PasswordCredential cred : subject.getPrivateCredentials(PasswordCredential.class)) {
operatorId = cred.getUserName();
operatorPassword = new String(cred.getPassword());

if (operatorId != null && operatorPassword != null) {

If I put a breakpoint, operatorId is always "" and operatorPassword is null. What's going on?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Joined: 2010-07-07

I'm fairly certain this is a glassfish bug... in ConnectionManagerImpl:

ResourceReferenceDescriptor ref =  poolmgr.getResourceReference(jndiNameToUse, logicalName);

        if (ref != null) {
            String shareableStr = ref.getSharingScope();

            if (shareableStr.equals(ref.RESOURCE_UNSHAREABLE)) {
                resourceShareable = false;

        //TODO V3 refactor all the 3 cases viz, no res-ref, app-auth, cont-auth.
        if (ref == null) {
            if(getLogger().isLoggable(Level.FINE)) {
                getLogger().log(Level.FINE, "poolmgr.no_resource_reference", jndiNameToUse);
            return internalGetConnection(mcf, defaultPrin, cxRequestInfo,
                    resourceShareable, jndiNameToUse, conn, true);
        String auth = ref.getAuthorization();

        if (auth.equals(ResourceReferenceDescriptor.APPLICATION_AUTHORIZATION)) {
            if (cxRequestInfo == null) {

                String msg = getLocalStrings().getString("con_mgr.null_userpass");
                throw new ResourceException(msg);
            ConnectorRuntime.getRuntime().switchOnMatching(rarName, poolInfo);
            return internalGetConnection(mcf, null, cxRequestInfo,
                    resourceShareable, jndiNameToUse, conn, false);
        } else {
            ResourcePrincipal prin = null;
            Set principalSet = null;
            Principal callerPrincipal = null;
            SecurityContext securityContext = null;
            ConnectorRuntime connectorRuntime = ConnectorRuntime.getRuntime();
            //TODO V3 is SecurityContext.getCurrent() the right way ? Does it need to be injected ?
            if (connectorRuntime.isServer() &&
                    (securityContext = SecurityContext.getCurrent()) != null &&
                    (callerPrincipal = securityContext.getCallerPrincipal()) != null &&
                    (principalSet = securityContext.getPrincipalSet()) != null) {
                AuthenticationService authService =
                        connectorRuntime.getAuthenticationService(rarName, poolInfo);
                if (authService != null) {
                    prin = (ResourcePrincipal) authService.mapPrincipal(
                            callerPrincipal, principalSet);

            if (prin == null) {
                prin = ref.getResourcePrincipal();
                if (prin == null) {
                    if (getLogger().isLoggable(Level.FINE)) {
                        getLogger().log(Level.FINE, "default-resource-principal not"
                                + "specified for " + jndiNameToUse + ". Defaulting to"
                                + " user/password specified in the pool");
                    prin = defaultPrin;
                } else if (!prin.equals(defaultPrin)) {
                    ConnectorRuntime.getRuntime().switchOnMatching(rarName, poolInfo);
            return internalGetConnection(mcf, prin, cxRequestInfo,
                    resourceShareable, jndiNameToUse, conn, false);

Notice how if a ResourceReferenceDescriptor isn't found, it just automatically sends null for the principal.

Joined: 2005-04-13

connector-work-security-map is used to map principal/user-group of EIS domain to Application server's security domain. (inbound communication),

connection-manager is for outbound communication.

Do you have either of :

1) config-property (for username and password) in the connection-definition of ra.xml

2) username, password properties in connector-connection-pool

3) Have a resource-ref defined in application's descriptor (eg: <resource-ref> in sun-web.xml/sun-ejb-jar.xml with <default-resource-principal> <name>xyz</name> <password>password</password></default-resource-principal>

In the above cases, you will receive the credentials (option-3 overrides option-2 overrides option-1 )

Joined: 2010-07-07

While #2 works, it's not the "correct" way to implement security. I should be able to map a JAAS alias to the adapter.

This is most definitely a bug in GlassFish however. If I inject my resource adapter:

name = "view/EchoService",
type = ViewManagerClientFactory.class,
authenticationType = AuthenticationType.CONTAINER)
ViewManagerClientFactory clientFactory;

GlassFish will note associate a JAAS alias. However, if I put a ejb-jar.xml file with the same info, it works as expected:

Joined: 2010-07-07