5 Replies Latest reply on Sep 26, 2007 2:32 PM by gilsontavares

    Can't integrate Web JAAS authentication with Seam Identity c

      Hi guys,

      I need to use SSO (Single Sign On) in my web apps and I have a LoginModule of my own declared in JBoss' login-config.xml.

      My web apps use request.getUserPrincipal() to get info 'bout the authenticated user. I'm trying to migrate to Seam and I just can't figure out how to make identity.getPrincipal() return the same info that request.getUserPrincipal() does.

      To authenticate in the container I must use a form with a "j_security_check" action, that makes request.getUserPrincipal() return the principal correctly but does not update identity's principal.
      If I configure components.xml with <security:identity jaas-config-name="a"/> and call identity.login(), my LoginModule is called and that updates identity but my calls to request.getUserPrincipal() return null.

      To go around the problem I'm authenticating twice, what is really bad. Seam's documentation, book, forum and white papers don't mention this problem/scenario.

      Is there a way to accomplish this?
      Does anyone else with this kind of problem?

      I inspected the code in org.jboss.seam.security package and there is no way to update the identity's principal, even if I subclass it, cause the field is private. Can the development team make a remark about this subject? Is it possible to integrate the container security mechanism and Seam security components?

      Thanks in advance for any help.

      Gilson

        • 1. Re: Can't integrate Web JAAS authentication with Seam Identi

          Hi,

          I researched a bit more and found that org.jboss.seam.core.UserPrincipal returns the container's authenticated user created by my loginModule, cause it gets the reference from the request.getUserPrincipal(). Is there any way to make the identity object use this reference? Is there some "trick" in the components.xml that could be used to accomplish this? I believe that without this, calls to #{s:hasRole} and #{s:hasPermission} or the use of @Restrict won't work.

          Should I post this a feature request in JIRA?

          Thanks for any help!

          • 2. Re: Can't integrate Web JAAS authentication with Seam Identi

            I have not seen direct SSO support from Seam but I am currently populating the Identity using certificate authentication in a manner that you could use for SSO. You can intercept the login by placing an action in your pages.xml:

            <page view-id="/auth/login.xhtml" action="myIdentity.checkLoggedIn" />


            This will always execute the myIdentity.checkLoggedIn() action prior to rendering login.xhtml. If the user is logged in, you can populate the Identity instance and redirect to wherever the user was going.

            If anyone is aware of SSO support, I would certainly be interested to know as well. Thanks.

            • 3. Re: Can't integrate Web JAAS authentication with Seam Identi

              Hi guys,

              thanks Jacob for your notes.

              I thought 'bout this solution too, but the real problem is the UserPrincipal reference, not the roles. There is a method in the identity object to add roles but no way to set a pre-existing Subject or Principal. That's the problem.

              The use of java security APIs in web apps is tricky. You are not supposed to have a login form where the user can authenticate himself beforehand. You can only configure a form to be presented when he tries to access a protected / secured resource of your app, and only through this form the container is aware that the authentication occurred and appends this information in every request from this point on. You can access this information using request.getUserPrincipal() (not Seam approach) or org.jboss.seam.core.UserPrincipal. Our solution is to create a form the user can fill and the action of this form redirects the request to a protected page "/private/abcd.seam" that only change the browser's location object to "/public/abcd.seam". In my web.xml I have:

               ...
              
               <security-constraint>
               <web-resource-collection>
               <web-resource-name>My Private Pages</web-resource-name>
               <url-pattern>/private/*</url-pattern>
               </web-resource-collection>
               <auth-constraint>
               <role-name>*</role-name>
               </auth-constraint>
               </security-constraint>
              
               ...
              
               <login-config>
               <auth-method>FORM</auth-method>
               <realm-name>myRealmName</realm-name>
               <form-login-config>
               <form-login-page>/jaasLogin.seam</form-login-page>
               <form-error-page>/jaasLoginError.seam</form-error-page>
               </form-login-config>
               </login-config>
              
              ...

              So, when I redirect the request to "/private/abcd.seam", the container automatically sends "/private/jaasLogin.seam" to the user. This page content does an immediate form submission using the information the user supplied im my official login form:
               <body onload="document.forms[0].submit();">
               <form method="post" action="j_security_check">
               <input type="hidden" name="j_username" id="j_username" value="#{user.username}" />
               <input type="hidden" name="j_password" id="j_password" value="#{user.password}" />
               </form>
               </body>
              


              This way, my LoginModule is invoked and the authentication happens as it is supposed to and when the private page is finally reached it redirects the user to the real "after Login page" of my initial web app. From this moment on, the user has access granted to all my "/private/*" pages. As I configured my JBoss to use SSO, all my apps will receive the userPrincipal of this first app, that mainly configures the public and private options of all other apps. So all my apps see the user as already authenticated, granting access to their "/private/*" pages too. In these pages I want to use #{s:hasRole} and #{s:hasPermission} and @Restrict to further define user's permissions.

              My problem is that as I can't push this userPrincipal into the identity object, a pre-condition to use Seam permission checking, I am being forced to authenticate the user again, configuring the identity in the components.xml file to use the same realm declared im my web.xml:
               <security:identity jaas-config-name="myRealmName" />

              I end up with 2 Principal objects I must keep in sync. I think that would be great if Seam was able to "detect" that there is an already authenticated user information available (when using JAAS, of course) and use it or, at least, allow the developer to do that.

              I asked for an opinion from the development team but until now no one answered. Maybe my approach is completely wrong and I should be doing something completely different. Maybe it is a completely absurd idea change the way Seam's security framework was designed. But as far as I can see with my limited view of the JAAS support in Seam, it seems SSO was not considered.

              Sorry if this message is too long. Sorry if I insist, but I really would like to hear from the development team about this. :)

              Thanks.

              Gilson

              • 4. Re: Can't integrate Web JAAS authentication with Seam Identi

                I know you want to hear from the Seam team but after doing some research for my own personal interest here are a few links for your reference:

                http://jira.jboss.org/jira/browse/JBSEAM-1032

                A similar workaround to what I was mentioning:

                http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4086376#4086376

                Good luck.

                • 5. Re: Can't integrate Web JAAS authentication with Seam Identi

                  Sorry Jacob, it was not my intention to sound rude, disrespectful or unconsidered. Thank you a lot for the links you posted, they are very interesting. In second link, however, the code presented does not solve the problem I mentioned. I couldn't grasp where the identity's Principal is updated with the SSO's Principal. But I am relieved that Shane will provide this integration in 2.0.1 release.

                  And, please, if you find anything else 'bout this let me know.

                  All the best,

                  Gilson