11

I have two java webapps who run on the same jboss server but in a different domain:

All content from both websites is secured by using a JAAS loginmodule. I would now like to create a button inside app1 to go to a page on app2. As predicted, I'm presented by the loginscreen from app2. I can succesfully login.

However, users on both webapps are actually the same. that means that username/passwords that are valid for app1 are also valid on app2. I would like to program something to bypass the redundant security check. If app 1 wants to access a page from app2, I would like to somehow pass along the j_username and the j_password to app2 sothat app2 can immediately perform the security check. It's not a problem if I have to create additional controller or jsp and use a redirect in this process. How can I directly pass a j_username and j_password so that the loginscreen is no longer shown, but the security check is still performed?

user1884155
  • 3,616
  • 4
  • 55
  • 108
  • How can you have different port1 & port2 for same jboss? Is it one Jboss instance and port1==port2 ? – sibnick Dec 17 '15 at 10:24
  • It's one server (machine), with a jboss domain setup. So there are multiple instances / server groups. The second group has a port offset. – user1884155 Dec 17 '15 at 17:16

2 Answers2

4

What do you need is to implement Single sign-on (SSO) using JAAS. Here you can find a tutorial that is using LDAP as login modules, but you will get the idea.

Since you already have the JAAS part already configured, you will only need to focus on the SSO part described starting with page 3. Basically, the idea is to configure one of the modules to share the state using useSharedState=true with the other application.

In your LoginModule you will use something like:

public boolean login() throws LoginException{
  // ...
  String username = null;
  String password = null;
  // check if useSharedState is true, if it is true, use the 
  // username/password from shared state.
  if ("true".equalsIgnoreCase(option_.get("useShardState"))) {
    username = (String)sharedStateMap_.get("javax.security.auth.login.name");
    password = (String)sharedStateMap_.get("javax.security.auth.login.password");
  } else {
    // get the username and password from the CallbackHandler
    Callback [] callbacks = {new NamePasswordCallback()};
    handler_.handle(callbacks);
    username = callback.getUserId();                
    password = callback.getPassword();
    //save the username and password into the shared state
    sharedStateMap.put("javax.security.auth.login.name",username);
    sharedStateMap.put("javax.security.auth.login.password",password);
  }
  // ... communicates with data store to authenticate this user     
}

Since in your other question, you mentioned that you are using JBoss, since JBoss version 5.0, you can use:

<Valve className="org.apache.catalina.authenticator.SingleSignOn" debug="0"></Valve>

This will handle the SSO automatically for you, if you are using the WebAuthentication class.

Sevle
  • 3,109
  • 2
  • 19
  • 31
dan
  • 13,132
  • 3
  • 38
  • 49
  • the WebAuthentication class is no longer available in JBOSS 7. I'm not sure why it was removed. Are there any alternatives to that class? – user1884155 Dec 17 '15 at 17:19
  • The example you link to assumes both webapps are running on the same server instance. I'm actually using JBOSS in domain mode, and I have two server instances on the same physical "server machine". Can single sign on be achieved across multiple instances? – user1884155 Dec 17 '15 at 17:46
  • @user1884155 Yes `SSO` works across physical machines. – dan Dec 17 '15 at 18:17
  • @user1884155 In `JBoss 7` where is an equivalent class, named: `Servlet3AuthenticationFilter`, that is using `Servlet 3` specs. – dan Dec 17 '15 at 18:26
  • How will the sharedstate map be populated on the other server instances? Is some request property, or cookie being embedded in the request that your browser makes when accessing website2 after logging in to website1, and jboss detect this to populate the sharedmap? – user1884155 Dec 17 '15 at 18:27
  • If you are using `JBoss` you should use the `valve` approach, it is handling the details behind the scene for you. See here: http://www.mastertheboss.com/jboss-server/jboss-security/configuring-single-signon-on-jboss-as-7 the details for JBoss 7. If you are willing to implement the logic on your own then you need to include the `sharedStateMap` parameters in the session/request. – dan Dec 17 '15 at 18:31
2

JAAS login works for security domain, not for webapp. So you should just put both application into one security domain. It is login-config section in web.xml:

   <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>ApplicationRealm</realm-name>
       <form-login-config> ...............</form-login-config>
   </login-config>

It should be enough for single sign-on inside one J2EE container.

It is directly specified in Java EE spec:

EE.3.3.8.2 Web Single Signon

......Require re-authentication of users only when a security policy domain boundary has been crossed............

EDIT

After some discovery I found that SSO is disabled by default in Wildfly. For enabling SSO in Wildfly:

  1. Modify standalone.xml and add <single-sign-on path="/"/> inside <host> tag
  2. Add jboss-web.xml (sso - your security domain)

       <jboss-web>
            <security-domain>sso</security-domain>
               <valve>
                  <class-name>org.apache.catalina.authenticator.SingleSignOn</class-name>
               </valve>
       </jboss-web>
    

After this Wildfly will use special cookie JSESSIONIDSSO for SSO

sibnick
  • 3,995
  • 20
  • 20
  • At this moment, we do not have a realm-name configured in our web.xml. What is the default value if I don't put a realm-name? Are you saying that if I give both websites a random realmname (for example: realmXYZ) I will have activated some kind of secret "single sign on" modus, without requiring any further configuration? – user1884155 Dec 17 '15 at 17:26
  • Both my webapps use the same security domain. That is, in my JBoss domain.xml file I have a secuerity-domain "xyz", and in each webapp's jboss-app.xml file I link them to this security domain. I haven't set a realm-name anywhere. What's the difference/hierarchy between realm names and security domains? – user1884155 Dec 18 '15 at 09:24
  • security policy domain == realm – sibnick Dec 18 '15 at 10:09
  • [Difference between security-realm and security-domain in WildFly](http://stackoverflow.com/questions/31036090/difference-between-security-realm-and-security-domain-in-wildfly) – sibnick Dec 18 '15 at 10:16
  • Does it matter if I use a standalone setup or a domain setup (multiple server instances in one jboss)? I'm not seeing any changes if both apps have the same realm-name. – user1884155 Dec 18 '15 at 12:12
  • Yes it matters. You may test standalone setup with two war apps. – sibnick Dec 18 '15 at 12:45
  • Ok so I have a standalone with one security-domain. Both webapps use this domain, and in their web.xml in the login-config they specify the same realmname. When I log into site1, and then go to site2, I'm stil presented with the loginscreen to authenticate myself. However, and now comes the strange part: When I submit the j_username/j_password to j_security_check, the login() method which I implemented in my loginmodule no longer run! Jboss somehow already knows everything it needs to know? Problem is, I still get to see the loginscreen :( – user1884155 Dec 18 '15 at 17:23
  • I think it is related to login-module cache. See my new edit – sibnick Dec 19 '15 at 07:27