[Security] - JBoss Programmatic Login, non-password authentication
by pgib
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#4270078
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4270078
15 years
[JCA] - Re: RAR classloading inversion
by kukeltje
Ok this helps... I did know about the transformations of -ds.xml to -service.xml but still was under the impression a basic -service.xml, overridden (where needed) with the generated one.
The docs you refer to (and later versions) are what I used. Read them from front to back and reverse, top-left to bottom right and reverse. These are also the docs that mention XATxConnectionManager class, so that is why I still thought it was needed. That confuses a lot, getting refered (not specifically by you, more in general) to use these docs but if the info in it is 'obsolete' (there is a JBoss 5 doc which also still has this chapter)
I'll certainly go for the JBoss 5 only solution, but trying the TXConnectionManager first is my quickest win.
Thanks again, I'll make sure to blog about this if I get it to work (and I do not see a reason why I wouldn't)
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4270075#4270075
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4270075
15 years
[jBPM Users] - Re: deploy() takes an awefully LONG time
by ajaygautam
This statement takes all the time:
| ProcessDeployer.java line 134, method checkKey().
|
|
| List<ProcessDefinition> existingProcesses = repositorySession.createProcessDefinitionQuery()
| .processDefinitionName(processDefinitionName)
| .list();
|
Then the code goes on to perform a "find":
| for (ProcessDefinition existingProcess: existingProcesses) {
| if (!processDefinitionKey.equals(existingProcess.getKey())) {
| deployment.addProblem("invalid key '"+processDefinitionKey+"' in process "+processDefinition.getName()+". Existing process has name '"+processDefinitionName+"' and key '"+processDefinitionKey+"'");
| }
| }
|
uuumm.... shouldn't the query actually be performed at the database level !?!?
On top of that, here is the code that performs the actual query:
| public Object execute(Session session) {
| List<Map<String, Object>> propertyMaps = (List<Map<String, Object>>) super.execute(session);
|
| List<ProcessDefinition> processDefinitions = new ArrayList<ProcessDefinition>();
| for (Map<String, Object> properties: propertyMaps) {
| String deploymentId = properties.get("deploymentDbid").toString();
| String objectName = (String)properties.get("objectName");
| RepositorySession repositorySession = EnvironmentImpl.getFromCurrent(RepositorySession.class);
| ProcessDefinitionImpl processDefinition = (ProcessDefinitionImpl) repositorySession.getObject(deploymentId, objectName);
| processDefinitions.add(processDefinition);
| }
|
| return processDefinitions;
| }
|
So, instead of loading everything from the database in one go, its loading data one row at a time! - FROM THE DATABASE !! HOLY PENGUIN!
Whats going on?
The symptom is magnified, by the fact that the process is running in US, and the database is in UK!
Or am I using it wrong?
Ajay
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4270066#4270066
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4270066
15 years