Hello. I am having difficulty determining how to perform programmatic login in JBoss
where the credentials is more complex than a simple username + password pair.
In our system, users are identified by UserName (String), AuthAgentId (long), and
VerificationCode (String). Basically, AuthAgentId is the "domain"; each one is
an independent namespace of UserNames. VerificationCode is a SHA-256 signature that we
use to verify the authenticity of the user.
Therefore we have a custom LoginModule:
import org.jboss.security.auth.spi.AbstractServerLoginModule;
|
| public class VhmDbServerLoginModule extends AbstractServerLoginModule {
| public void initialize(...) { ... }
| public boolean login () throws LoginException { ... }
| ...
| }
Also, we have a custom CallbackHandler to actually feed the LoginModule:
public class UsernameAuthAgentHandler implements CallbackHandler {
| private transient final String username;
| private transient final String verificationCode;
| private transient final long authAgentId;
|
| public UsernameAuthAgentHandler (
| String username, long authAgentId, String verificationCode) {
| ...
| }
|
| public void handle (Callback[] callbacks) throws
| UnsupportedCallbackException {
| for (Callback c : callbacks) {
| if (c instanceof NameCallback) {
| NameCallback nc = (NameCallback) c;
| nc.setName(username);
| }
| else if (c instanceof TextInputCallback) {
| TextInputCallback tc = (TextInputCallback) c;
| if (tc.getPrompt().equals("VerificationCode")) {
| tc.setText(verificationCode);
| }
| }
| else if (c instanceof LongInputCallback) {
| LongInputCallback lc = (LongInputCallback) c;
| if (lc.getPrompt().equals("AuthAgent")) {
| lc.setValue(authAgentId);
| }
| }
| else {
| throw new UnsupportedCallbackException(c, "Unrecognized Callback");
| }
| }
| }
| }
Good so far - We use LoginContext to perform the login:
Request request = SecurityAssociationValve.activeRequest.get();
| if (request == null) {
| throw new IllegalStateException("request is null");
| }
|
| UsernameAuthAgentHandler uaah =
| new UsernameAuthAgentHandler(username, agentId, credential);
|
| String realm = request.getContext().getLoginConfig().getRealmName();
| LoginContext lc = null;
| try {
| lc = new LoginContext(realm, uaah);
| lc.login();
| }
| catch (LoginException le) {
| return false;
| }
| ...
This works, it results in a subject that looks like:
Subject:
| Principals:
| Principal: com.vhm.security.auth.UserPrincipal@65824b9
| Principal: Roles(members:OWNER,SUBSCRIBER,ACCESS_FULL)
| Principal: CallerPrincipal(members:com.vhm.security.auth.UserPrincipal@65824b9)
| pubCredentials: size = 0
| privCredentials: size = 0
I can share the exact LoginModule code incase this output looks invalid, but it seems
correct to me.
I then call the WebAuthentication.register(Request request, Principal principal, String s,
Object o) method. I created a subclass of WebAuthentication in order to make the method
public. Principal p =
| lc.getSubject().getPrincipals(UserPrincipal.class).iterator().next();
| wad.register(request, p, username, credential);
After all this, I make another request to a servlet. I call request.getUserPrincipal() and
it returns my custom UserPrincipal! However, when I call
request.isUserInRole("OWNER") I get false. I expect this since I never had a
chance to register the roles.
My question is - How do I actually register the roles with the request/session? Some
people in #jboss tell me to "Create a SAR". I know how to do this, but I have
absolutely no clue what this Service should do. I have no existing services I know to
fork. So - I'm at a total loss.
If someone could please help me register the roles with the catalina session, I would be
eternally grateful!
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4270078#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...