问题
I have a JASPIC auth module that works really well on GlassFish, WildFly and WebLogic.
Now we have a new customer who uses WebSphere 8.5, and I can't get the auth module to run properly there.
The problem is that WebSphere doesn't accept the username that the auth module puts in the CallerPrincipalCallback. Our other supported servers just accept this, but WebSphere for some reason thinks it needs to perform some extra checks.
After investigating the issue I stumbled upon this one: https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014937852
This exactly describes my problem, but there's no solution given there.
How can I confince WebSphere to just process the CallerPrincipalHandler and accepting any username like all other servers do?
回答1:
The behavior attributed to WebSphere 8.5, WRT the processing of the JASPIC CallerPrincipalCallback is NOT compatible with the JASPIC specification.
The CallerPrincipalCallback(s) must be able to support the case where the user registry is integrated within the SAM, including for the purpose of providing user group memberships.
For the special case of password based validation, A SAM can invoke the container provided CallbackHandler to handle a PasswordValidationCallback; in which case the CallbackHandler will return a failure result if the username and/or password combination does not exist in the user registry integrated with the container's CallbackHandler. In that case, the SAM would return a failed (or continuation) authentication result and would NOT invoke the CallbackHandler to handle the CallerPrincipalCallback.
HTH,
Ron Monzillo
回答2:
In general I usually advise to use container authentication/authorization, if possible, as it is already provided by server infrastructure and for majority of cases sufficient.
However, if in your case you need it, here are some hints.
If you want to avoid extra checks, and allow authentication of users that are not in the WebSphere user registry you have to create full subject like this (this is fixed user simplification), instead of using callbacks:
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject,
Subject serviceSubject) throws AuthException {
String uniqueid = "test";
String username = "test";
String password = "test";
Hashtable hashtable = new Hashtable();
hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_PASSWORD, password);
List groups = new ArrayList();
// if you want to use existing group uncomment this
// com.ibm.websphere.security.UserRegistry reg =
// (com.ibm.websphere.security.UserRegistry) ctx.lookup("UserRegistry");
// String groupID reg.getUniqueGroupId("testers");
// groups.add(groupID); // for federated registry it returns cn=testers,o=defaultWIMFileBasedRealm
// if you want to use fake groups just add them here, and provide correct binding file - see below. If you don't want to use groups just omit WSCREDENTIAL_GROUPS
groups.add("testers");
hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groups); //optional
hashtable.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY, "myCustomAttribute" + uniqueid);
clientSubject.getPrivateCredentials().add(hashtable);
return AuthStatus.SUCCESS;
}
I'm assuming that you want to map these users to some security roles in your application. You can map it either using users, groups or special subject. You need to have roles defined in your application.xml
, like this:
<security-role>
<role-name>user</role-name>
</security-role>
and you will need binding file, since binding cannot be done via console for non-existing users/groups. Create ibm-application-bnd.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<application-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-application-bnd_1_2.xsd"
version="1.2">
<security-role name="user">
<user name="test" access-id="user:defaultWIMFileBasedRealm/test"/>
<group name="testers" access-id="group:defaultWIMFileBasedRealm/testers"/>
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
I provided sample for all kinds of mappings, use the one that suits your needs:
user
- for mapping named users to rolegroup
- for mapping group to rolespecial-subject
- if you want any successfully authenticated user to have that role.
Important if you want to use fake users/groups you have to provide access-id
attribute, if they are in the registry then just provide name
.
See also:
- Developing a custom JASPI authentication provider
来源:https://stackoverflow.com/questions/27686626/use-jaspic-auth-module-on-websphere-8-5