<snip>
InitialContext ctx = new InitialContext();
String str = (String) ctx.lookup("thisNode/cell/legacyRoot/string/myUserPass");
lc = new LoginContext("DefaultPrincipalMapping", new WSPrincipalMappingCallbackHandler(str, null));
lc.login();
javax.security.auth.Subject subject = lc.getSubject();
java.util.Set creds = subject.getPrivateCredentials();
result = (javax.resource.spi.security.PasswordCredential) creds.toArray()[0];
servlet.getServletContext().setAttribute("user", result.getUserName());
servlet.getServletContext().setAttribute("password", new String(result.getPassword()));
</snip>
There seems to be a problem with the line
lc = new LoginContext("DefaultPrincipalMapping", new WSPrincipalMappingCallbackHandler(str, null));
in regards to the null. I get the following error..
SECJ4030E: Unrecognizable Callback index = 0 com.ibm.wsspi.security.auth.callback.WSManagedConnectionFactoryCallback@16a8bf0
Can somebody help me read the user id and password out of the J2C Authentication Data?
Thanks.
I'm not sure, but maybe you can do a getProperties() on the
WSMappingPropertiesCallback.
Here's the javadoc:
Thanks for the help so far.
Well, you can just store them in a file. In case you are thinking that
it would be more secure to store them in the J2C entry, that's really
not the case, as any application can lookup a J2C entry - there's no
authorization on that access. At least with a file you would have the
ability to protect the file itself with OS security, and the ability to
protect access from Java code in WAS by enforcing Java 2 security.
I don't know if storing username/password in a file is more secure than using J2C. But if all applications in that server share same J2C, maybe it's not an issue anymore. I understand J2C is not that secure, but it's many companies policy not to include user name/password in a plain text file. And unless J2C is deprecated in WAS6, there's should be a way to use it somehow. I just want to see some simple same code that read J2C entries, so far I found none.
I've been told that while it may be possible to get this to work, it
isn't supported using public APIs. I'll post more if I find out more.
I hope you find the solution and post it here. Since I'm sure there're other people who are looking for the same solution.
Thanks again
Possible solution - needs to be tested:
Create a new JAAS login config with two modules:
1. The WAS identity mapping module
2. Your custom module
- the identity mapping module should create a subject in shared state,
and your module should be able to get the userid and pwd out of it.
Try this, and post back if it works.
You should instead use WSMappingCallbackHandler. But IBM realized their infocenter example is not correct. From you code, change following line
lc = new LoginContext("DefaultPrincipalMapping", new WSPrincipalMappingCallbackHandler(str, null));
to this
HashMap map = new HashMap();
map.put("com.ibm.mapping.authDataAlias", str);
// or com.ibm.wsspi.security.auth.callback.Constants.MAPPING_ALIAS is "com.ibm.mapping.authDataAlias"
// map.put(Constants.MAPPING_ALIAS, str);
javax.security.auth.callback.CallbackHandler callbackHandler = WSMappingCallbackHandlerFactory.getInstance().getCallbackHandler(map, null);
lc = new LoginContext("DefaultPrincipalMapping", callbackHandler);
Just beware, WAS6 now prefix cell or node name in front of J2C authentication data's alias name. So, you should look for the alias name that includes cell or node name.