1 2 3 Previous Next 61 Replies Latest reply on May 28, 2007 1:36 PM by Carlos Abreu

    JAAS and SEAM

    blalls asdsd Novice

      I am interested in the posibility to integrate a jaas login module for seam. IS it possible to use jaas for security side of seam?

        • 1. Re: JAAS and SEAM
          Gavin King Master

          Of course!

          Seam components are EJBs, so you can just use EJB security, which in JBoss is using JAAS.

          • 2. Re: JAAS and SEAM
            blalls asdsd Novice

            I see. But is there any effort to do this? It sould be nice to have a security platform integrated with seam. We would need login Module, annotation and etc.
            It also would be a good isea if the example use JAAS for authentication and authorization instead of a custom flag in the session? could it be done?

            • 3. Re: JAAS and SEAM
              Thomas Heute Master

              There is nothing specifically related to Seam so there is no interest in adding JAAS to our examples since some people could be bothered by this extra noise.

              If you find out a better way to integrate security to Seam than the standard way let us know.

              • 4. Re: JAAS and SEAM
                Gavin King Master

                 

                "armita" wrote:
                I see. But is there any effort to do this? It sould be nice to have a security platform integrated with seam. We would need login Module, annotation and etc.


                I truly don't understand. JAAS is already integrated in EJB3. Just use EJB3 security. Seam sits on top of EJB3.

                "armita" wrote:
                It also would be a good isea if the example use JAAS for authentication and authorization instead of a custom flag in the session? could it be done?


                If what you are thinking is that @LoggedIn is the way to do authorization in Seam, it is not. @LoggedIn is there to do nice automatic redirects to the login page. It is most certainly *not* a replacement for a proper security infrastructure such as already exists in EJB3.

                • 5. Re: JAAS and SEAM
                  Patrick Angeles Novice

                  It's not that simple... there's two security concerns here:

                  1. Web Security, which restricts access based on URL
                  2. EJB Security which restricts access to EJBs and methods.

                  If you're using the JSF/Seam/EJB3 stack simply for web applications, then Web Security is enough and EJB security is overkill. You need EJB security if the EJB3 layer will be accessed by other clients (such as remote Swing apps). You can get by with just EJB security, but it's not the most elegant thing for web apps.

                  Tomcat 5 provides a JAASRealm (still unofficial "beta"). However, the user principal that you get from doing this does not propagate to the EJB3 layer. Nor does it put the "user" entity in the session object, which is common practice in web applications. (You have to do this yourself.) Worse, there doesn't seem to be a way to do web container based authentication completely within JSF/Faces (by that I mean using JSF nav rules, XHTML for the login page, etc.)

                  I've been trying to get my arms around this issue for a good month now and I still haven't seen or figured out a good solution that will fit my needs using JAAS and JSF/Facelets. After all my research, I think I'm going to resort to a homebrew solution that involves servlet filters, with JSF/Seam/EJB3 handling all the rest (loading user roles, "outjecting" the user entity to the session-context, etc.). I'll post my solution as soon as I'm done, but my plan is simple:

                  1. login page / action similar to LoginAction in the booking example. (@LoggedIn probably won't be needed anymore.)
                  2. login action outjects the user entity to the session.
                  3. user entity has one-to-many "roles" (eagerly fetched).
                  4. "roles" have permission to view URLs (defined as regex patterns). this has to be in an xml config file to be loaded on startup by the servlet filter (see below).
                  5. servlet filter looks for the user entity in the session context, matches the current URL against those defined in the xml config, and sees if the user is in one of the roles allowed by the matching URL.
                  6. if so, servlet filter continues (processing is handed to the faces servlet). otherwise, the browser is forwarded to an error page.

                  I think this should work. My only concern is JSF's use of "postbacks" and whether that will play tricks on URL-based authorization.

                  • 6. Re: JAAS and SEAM
                    Gavin King Master

                    Surely in the context of JBoss, Tomcat is going to be delegating to JBoss' security infrastructure?

                    No??

                    • 7. Re: JAAS and SEAM
                      Thorsten Kunz Novice

                      Well I was also looking at a way to use the container based JAAS cababilities of Tomcat to do webauthentication. I have it working as I wanted it to work but the implementation is not how I want it to look like:

                      1. I have written a custom LoginModule that extends UsernamePasswordLoginModule and utilises a few EJB3 Entity beans to pull users and roles from my datamodel.

                      2. web.xml

                       <security-constraint>
                       <web-resource-collection>
                       <web-resource-name>your res name</web-resource-name>
                       <url-pattern>/*</url-pattern>
                       </web-resource-collection>
                       <auth-constraint>
                       <role-name>AuthorizedUser</role-name>
                       </auth-constraint>
                       <user-data-constraint>
                       <transport-guarantee>NONE</transport-guarantee>
                       </user-data-constraint>
                       </security-constraint>
                       <security-role>
                       <description>
                       The role required to access restricted content
                       </description>
                       <role-name>AuthorizedUser</role-name>
                       </security-role>
                       <!-- ... -->
                       <login-config>
                       <auth-method>FORM</auth-method>
                       <realm-name>Restricted Login</realm-name>
                       <form-login-config>
                       <form-login-page>/login.jsf</form-login-page>
                       <form-error-page>/error.jsf</form-error-page>
                       </form-login-config>
                       </login-config>
                      


                      3. Place a login.xhtml and error.xhtml into your root and make it look something like this (bare minimum shown):
                      [...HTML...]
                      <form action="j_security_check" method="post">
                      User ID:<input type="text" name="j_username" /><br/>
                      Password:<input type="password" name="j_password" />
                      <input type="submit" value="Login" />
                      </form>
                      [...HTML...]
                      


                      4. Change the LoggedInInterceptor to something like this to propagate a User object into your session:
                       @AroundInvoke
                       public Object checkLoggedIn(InvocationContext invocation) throws Exception {
                      
                       if (Contexts.getSessionContext().get("loggedIn") instanceof User) {
                       log.info("User is already logged in");
                       return invocation.proceed();
                       } else {
                       try {
                       Context ctx = new InitialContext();
                       SomeBeanWithUserEntityAccess bcl = (SomeBeanWithUserEntityAccess) ctx.lookup(SomeBeanWithUserEntityAccess.class.getName());
                       User user = bcl.getUser(invocation.getEJBContext().getCallerPrincipal().getName());
                       Contexts.getSessionContext().set("loggedIn", user);
                       log.info("pushed user="+user.getId()+" into SessionContext");
                       } catch(NamingException e) {
                       log.error(e.getMessage());
                       }
                       return invocation.proceed();
                       }
                      
                       }
                      



                      So what you get out of it:

                      - when a user tries to access any page that was protected with the pattern in you web.xml he/she will be redirected to the login.xhtml page.
                      - Username/password will then be checked by the JAAS subsystem and (depending on you login module) against your datamodel

                      This is my first attemp to work with JAAS so this may be a crappy solution but it seems to work the way I want it to. Major drawback is that your database has to take 2 hits (1 by the JAAS layer to check username/password, 2 when I am pulling the userobject in the interceptor out of the db to propagate it into the session) and that you still have to use the @LoggedIn interceptor to make sure that there is alway a User object in your "loggedIn" session variable.
                      It would be VERY nice if the JAAS subsystem would propagate a custom userobject into the session. Don't know if thats possible since I am new to JAAS an havent looked to deep into the LoginModule things yet. Maybe some JAAS guru can help out so that I don't need the LoggedInInterceptor anymore?

                      Any suggestions on how to make the thing a little cleaner?

                      • 8. Re: JAAS and SEAM
                        Thorsten Kunz Novice

                        a few more things to make the sample more complete:

                        1. put a login-config.xml into the META-INF dir of you .ear and make it look like this:

                        <policy>
                         <application-policy name="YourAuthPolicyName">
                         <authentication>
                         <login-module code="com.yourdomain.yourloginmodule"
                         flag="required" />
                         </authentication>
                         </application-policy>
                        </policy>
                        


                        2. put a login-service.xml into the root of your .ear that looks like this:
                        <server>
                         <mbean code="org.jboss.security.auth.login.DynamicLoginConfig"
                         name="jboss:service=DynamicLoginConfig">
                         <attribute name="AuthConfig">
                         META-INF/login-config.xml
                         </attribute>
                         <!-- The service which supports dynamic processing of login-config.xml
                         configurations.
                         -->
                         <depends optional-attribute-name="LoginConfigService">
                         jboss.security:service=XMLLoginConfig
                         </depends>
                         <!-- Optionally specify the security mgr service to use when
                         this service is stopped to flush the auth caches of the domains
                         registered by this service.
                         -->
                         <depends optional-attribute-name="SecurityManagerService">
                         jboss.security:service=JaasSecurityManager
                         </depends>
                         </mbean>
                        </server>
                        


                        3. put a jboss-app.xml into the META-INF of your .ear
                        <jboss-app>
                         <loader-repository>
                         yourdomain.com:loader=yourappname
                         </loader-repository>
                         <module>
                         <service>login-service.xml</service>
                         </module>
                        </jboss-app>
                        


                        4. put a jboss-web.xml into the WEB-INF dir of your .war like this:
                        <jboss-web>
                         <security-domain>java:/jaas/YourAuthPolicyName</security-domain>
                        </jboss-web>
                        



                        Cheers, Thorsten

                        • 9. Re: JAAS and SEAM
                          Scott Stark Master

                          JAAS is indepedent of any container layer so it knows nothing about the existence of a session. Your login module can choose to be coupled to a particular container and access the servlet request to populate the session if it wants as described here:

                          http://wiki.jboss.org/wiki/Wiki.jsp?page=AccessingServletRequestForAuthentication

                          The containers need a better mechanism for externalizing the authentication phase. JSR196 is the current proposal in this area that we are pursuing.

                          • 10. Re: JAAS and SEAM
                            Patrick Angeles Novice

                            SunFire,

                            Nice work. As for taking out the LoggedIn interceptor, I wonder if using a servlet filter could do the same trick. This at least frees you of using the @LoggedIn annotation. Another thing is that you don't have to rely on a backing bean instantiation for the User to make it into the session.

                            • 11. Re: JAAS and SEAM
                              Micah Schehl Newbie

                              I don't understand the desire to protect a Seam project using web.xml's security descriptors. It seems to me that a much stronger security would be implemented using annotations.

                              I would want to see an annotation called @RequireUserType or @RequireUserRole.

                              @Stateful
                              @Name("search")
                              @LoggedIn
                              @RequireUserType("customer")
                              @Interceptors(SeamInterceptor.class)
                              public class SearchAction
                              ...
                              


                              Or would it make sense to put the annotation on the methods of the class, too?


                              Also, the @LoggedIn should remember the url, and in Seam, it would make sense that if the url was in the middle of a conversation, after login the user would be taken to a page that would start the conversation.

                              Shouldn't Seam come packaged with these Login and Security check type of functionality built-in and overridable if needed?

                              • 12. Re: JAAS and SEAM
                                Gavin King Master

                                 

                                "mjschehl" wrote:
                                Shouldn't Seam come packaged with these Login and Security check type of functionality built-in and overridable if needed?


                                Perhaps, but the trouble is that I am not sure that all Seam apps will want to do security stuff in the same way and I am not enough of an expert on security to be able to decide what is the "best" way.

                                I figure that if it is easy to do this stuff by writing Seam interceptors (it is, I suppose), then for now we should leave it to the user, since they will do a better job of it...

                                If someone who is a true expert on this stuff wants to contribute something, I am very interested, however.

                                • 13. Re: JAAS and SEAM
                                  Grigoras Cristinel Newbie

                                   

                                  "gavin.king@jboss.com" wrote:
                                  "mjschehl" wrote:
                                  Shouldn't Seam come packaged with these Login and Security check type of functionality built-in and overridable if needed?


                                  Perhaps, but the trouble is that I am not sure that all Seam apps will want to do security stuff in the same way and I am not enough of an expert on security to be able to decide what is the "best" way.

                                  I figure that if it is easy to do this stuff by writing Seam interceptors (it is, I suppose), then for now we should leave it to the user, since they will do a better job of it...

                                  If someone who is a true expert on this stuff wants to contribute something, I am very interested, however.


                                  We have any working example using JAAS ? My JAAS authentification was broken after upgrading to seam1.0beta2.

                                  • 14. Re: JAAS and SEAM
                                    Dennis Wenger Newbie

                                    I'm also interested in a working example. Best with DatabaseServerLoginModule.

                                    All Help welcome, I'm stuck.

                                    Dennis

                                    1 2 3 Previous Next