1 2 3 4 5 Previous Next 61 Replies Latest reply on May 28, 2007 1:36 PM by carlos.abreu Go to original post
      • 45. Re: JAAS and SEAM
        gavin.king

         

        "mirko27" wrote:
        gavin, is there any way to talk with you more real-time? I would start with tutorial then, but I have few questions.


        I'm travelling a lot at the moment, so not really. Just post here, or if its more private, send me email. Whichever way I will answer as soon as I get a chance.

        • 46. Re: JAAS and SEAM
          dalvarezpy

          Hello guys. Well this topic is getting long, but I didn't want to start another, JAAS & SEAM is exactly what I want to talk about.

          This is the thing: I've got an existing JSP/J2EE "legacy" web app. This has a working JAAS security schema working just fine, with user, roles, etc. I want now my new SEAM application to just "use" the existing security domain from my old web-app. I did something more of less following SunFire and Dr. Coetzee's examples, only that I used DatabaseServerLoginModule to perform authentication.

          Now I have just everything "protected" on a URL basis: everything in under the security domain, and user has to authenticate when trying to access protected web resources. But I need something more fine-grained.

          My question is now: how do I "use" my security framework from within SEAM? I mean, I'd like to customize the views according to the roles the user have (e.g. show a given button only to Admins), so I would like to know any moment what roles the user have, for example. Is there a way to do this?

          • 47. Re: JAAS and SEAM
            sunfire

             

            "dalvarezpy" wrote:
            My question is now: how do I "use" my security framework from within SEAM? I mean, I'd like to customize the views according to the roles the user have (e.g. show a given button only to Admins), so I would like to know any moment what roles the user have, for example. Is there a way to do this?

            The approach I use to employ the JAAS model in JSF is to use the Tomahawk extensions. Most of their components have a "enabledOnUserRole" and/or "visibleOnUserRole" attribute. These roles are JAAS roles.
            So you could use something like
            <t:commandLink visibleOnUserRole="Developer,Administrator" value="yehaa" action="somethingimportant" />
            to hide the linke to anybody but users with JAAS role Developer or Administrator.
            For tags which don't have these attributes you could add a mathod like this
            public Map<String, Boolean> getRoleList();
            to your User object (the Map has to be populated somehow with all and the roles the users is assigned to) and use the standard JSF tags with their "rendered" attribute like this
            <h:commandLink rendered="#{loggedInUserObject.roleList['Developer'] or loggedInUserObject.roleList['Administrator']}" value="yehaa" action="somethingimportant" />
            to achieve very much the same as with the Tomahawk extensions.
            Or another option would be to just use the Tomahawk "div" component to wrap it around tags which do not have role ACL capabilities on their own.

            Hope it helps

            • 48. Re: JAAS and SEAM
              lcoetzee

              The tomahawk stuff works well. However, I have changed most of my code to use the Seam s:link as provided by Gavin quite recently (mostly because I was able to get away from the Javascript stuff ). In conjunction with the s:link he also exposed the "isUserInrole" which makes life a lot easier.


              <f:subview rendered="#{isUserInRole['ServiceManager']}">
               <li><s:link action="#{serviceManagementBean.loadAllServices}"
               propagation="begin" id="serviceManagement">
               <h:outputText value="#{msgs.serviceManagement}" />
               </s:link></li>
               </f:subview>
              


              Regards

              Louis


              • 49. Re: JAAS and SEAM
                dalvarezpy

                Well that's GREAT. While trying the tomahawk stuff, refreshed this topic and saw the rendered="#{isUserInRole['Role']}" thing.
                I compiled the last SEAM, tried it, and JUST WORKED. Thanks Louis and SunFire, and Gavin for adding it.

                It's great to see how the things the community wants get "inserted" in the projects (SEAM in this case).

                Now, another little question (and I know, maybe a little OT, but anyway): having logged in with JAAS' j_security_check, the "standard" logout would be to
                invalidate the session, right. How do I do that with SEAM? Also, when the login fails, how do I "tell" the server to stay in login.jsp?

                Thanks again,

                Dario.

                • 50. Re: JAAS and SEAM
                  lcoetzee

                   

                  the "standard" logout would be to
                  invalidate the session, right. How do I do that with SEAM?

                  I do a
                  Seam.invalidateSession();



                  when the login fails, how do I "tell" the server to stay in login.jsp?


                  In your web.xml just change the form-error-page to point to your login page. Something like:

                  <login-config>
                   <auth-method>FORM</auth-method>
                   <realm-name>napEntityManager</realm-name>
                   <form-login-config>
                   <form-login-page>/login.jsp</form-login-page>
                   <form-error-page>/login.jsp</form-error-page>
                   </form-login-config>
                   </login-config>


                  • 51. Re: JAAS and SEAM
                    dloiacono

                    Hi,
                    I would like add one more complexity to JAAS-SEAM coexistance...

                    I'm writing a web application with jBPL pageflow....
                    I've used SunFire's solution with a login page like this:

                    login.xhtml

                    [...]
                    <form action="j_security_check">
                     <h:outputText value="#{bundle.label_username}" />
                     <input type="text" name="j_username" />
                    
                     <h:outputText value="#{bundle.label_password}" />
                     <input type="password" name="j_password" />
                    
                     <h:commandButton value="#{bundle.button_login}" action="login" rendered="true" />
                    </form>
                    [...]
                    


                    pageflow.jpdl

                    <pageflow-definition name="pageflow.jpdl">
                     <start-state name="start">
                     <transition to="login"/>
                     </start-state>
                     <page name="login" view-id="/login.seam" redirect="true">
                     <transition name="login" to="secure"/>
                     </page>
                     <page name="secure" view-id="/secure/home.seam" redirect="true">
                     <end-conversation />
                     </page>
                    </pageflow-definition>
                    


                    but it doesn't work.

                    Do you have any idea on JAAS - pageflow integration ?

                    • 52. Re: JAAS and SEAM
                      gavin.king

                      heh. You wish. :-(

                      AFAICT, there is no way to properly integrate JSF with servlet spec authentication. What the servlet spec has on this is a total disaster.

                      You'll need to use some Tomcat-specific stuff for this.

                      We are also trying to figure out a great solution to this.

                      • 53. Re: JAAS and SEAM
                        lcoetzee

                        I don't think that will work (but saying this with care as I haven't used the pageflow stuff yet).

                        With JAAS you cannot point to the login page directly. The way it works is the request gets intercepted when you are trying to access a secure resource (which pops up the login page). After the login JAAS (tomcat) then redirects you to the secure page you initially requested.

                        In short I don't think it is required for you to have a start state which is the JAAS login. Have the start state the secure page (e.g. secure.home.seam) ... thus when requesting the secure page JAAS/tomcat will do its bit first whereafter the jBPL will be in the right state. (Or something like that ;-)

                        Hope it helps.

                        Louis

                        • 54. Re: JAAS and SEAM
                          lcoetzee

                          Oops.. didn't see Gavin's reply in time! Bandwidth to Africa ;-)



                          • 55. Re: JAAS and SEAM
                            pmuir

                            Louis,

                            Superb example - allowed me to get everything up and running smoothly.

                            Thanks

                            Peter

                            • 56. Re: JAAS and SEAM
                              armita

                              How can I get the authenticated JAAS user in a seam application?

                              • 57. Re: JAAS and SEAM
                                pmuir

                                To get the username:

                                if ( facesContext.getExternalContext().getUserPrincipal() == null ) {
                                 // User not logged in
                                } else {
                                 String username = facesContext.getExternalContext().getUserPrincipal().getName().toString();
                                }


                                From this you can just use a normal EJB/Hibernate query to retrieve your User object from the database.

                                • 58. Re: JAAS and SEAM
                                  dloiacono

                                  Ok guys,
                                  I've integrated JAAS with Seam, Facelets, MyFaces and jBMP pageflow.
                                  It works very fine!

                                  I've started with the information written by SunFire and locoetze in this topic.
                                  In pageflow.jpdl.xml I've called an action that put in http session j_username and j_password.


                                  .....
                                   <start-state name="start">
                                   <transition to="index"/>
                                   </start-state>
                                  
                                   <page name="index" view-id="/login.xhtml" redirect="true">
                                   <transition name="doLogin" to="home">
                                   <action expression="#{login.doLogin}" />
                                   </transition>
                                   </page>
                                  
                                   <page name="home" view-id="/secure/home.xhtml" redirect="true">
                                   <end-conversation />
                                   </page>
                                  .....
                                  


                                  I have put my action in a Stateless Session Bean annotated with @Name("login"):

                                  ....
                                  @Stateless
                                  @Name("login")
                                  @Interceptors(SeamInterceptor.class)
                                  @Scope(ScopeType.CONVERSATION)
                                  public class LoginAction implements Login {
                                  
                                   private final static Log log = LogFactory.getLog(LoginAction.class);
                                  
                                   private String j_username;
                                   private String j_password;
                                  
                                   @In
                                   private FacesContext facesContext;
                                  
                                   @Create
                                   @Begin(pageflow="cooperative-pageflow")
                                   public void begin()
                                   {
                                   log.debug("begin pageflow");
                                   }
                                  
                                   public void doLogin()
                                   {
                                   log.debug("login");
                                   HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
                                   request.getSession().setAttribute("j_username", j_username);
                                   request.getSession().setAttribute("j_password", j_password);
                                   }
                                  
                                   public void doLogout() {
                                   //Contexts.
                                   }
                                  
                                   public String getJ_password() {
                                   return j_password;
                                   }
                                  
                                   public void setJ_password(String j_password) {
                                   this.j_password = j_password;
                                   }
                                  
                                   public String getJ_username() {
                                   return j_username;
                                   }
                                  
                                   public void setJ_username(String j_username) {
                                   this.j_username = j_username;
                                   }
                                  
                                  
                                  
                                  }
                                  



                                  After this I've changed login-config in web.xml by adding this line
                                  <form-login-page>/login</form-login-page>


                                  So <login-config> tag in web.xml appears like this..
                                  ....
                                   <login-config>
                                   <auth-method>FORM</auth-method>
                                   <realm-name>cooperative</realm-name>
                                   <form-login-config>
                                   <form-login-page>/login</form-login-page>
                                   <form-error-page>/index.seam</form-error-page>
                                   </form-login-config>
                                   </login-config>
                                  ....
                                  


                                  /login url call a LoginServlet that get j_username and j_password from http session and compose a JAAS url: /j_security_check?j_username=&j_password=

                                  package it.liser.cooperative.web.servlet;
                                  
                                  import java.io.IOException;
                                  
                                  import javax.servlet.ServletException;
                                  import javax.servlet.http.HttpServlet;
                                  import javax.servlet.http.HttpServletRequest;
                                  import javax.servlet.http.HttpServletResponse;
                                  import javax.servlet.http.HttpSession;
                                  
                                  /**
                                   * Servlet Class
                                   *
                                   */
                                  public class LoginServlet extends HttpServlet {
                                  
                                   static final long serialVersionUID = 1147420275339L;
                                  
                                   public LoginServlet() {
                                   super();
                                   }
                                  
                                   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                                   throws ServletException,
                                   IOException {
                                   doLogin(req, resp);
                                   }
                                  
                                   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                                   throws ServletException,
                                   IOException {
                                   doLogin(req, resp);
                                   }
                                  
                                   public void doLogin(HttpServletRequest request, HttpServletResponse response)
                                   throws javax.servlet.ServletException, java.io.IOException {
                                   // Grab the URI that was passed to login
                                   HttpSession hSession = request.getSession(true);
                                  
                                   String lUsername = (String)hSession.getAttribute("j_username");
                                   String lPassword = (String)hSession.getAttribute("j_password");
                                   // Redirect to the servlet's login method. This means we login twice
                                   // but we have to that or the server doesn't realise that we're logged
                                   // in and we get redirected back to the login page.
                                   java.lang.StringBuffer location = new java.lang.StringBuffer(request.getContextPath());
                                   location.append("/j_security_check?j_username=");
                                   location.append((lUsername != null) ? lUsername : "");
                                   location.append("&j_password=");
                                   location.append((lPassword != null) ? lPassword : "");
                                  
                                  
                                   // XXX We are sending password as a GET and that might be logged somewhere
                                   // on the server. Better to send it using POST. Perhaps using HttpClient?
                                   response.sendRedirect(response.encodeRedirectURL(location.toString()));
                                   }
                                  
                                  }
                                  


                                  So when you try to access first secured page, JAAS layer use j_username and j_password for login module.

                                  Gavin it's a good work ? ;-)

                                  Hope it helps
                                  Domenico

                                  • 59. Re: JAAS and SEAM
                                    matthewdemerath

                                    First I want to thank everyone who posted here. This has been a great help in figuring this JAAS/Seam integration out.

                                    In the spirit of the open source community I have uploaded a new sample application that uses LDAP and UsersRolesLoginModule. I had some trouble getting the other example running because I didn't have Postgres.

                                    http://www.jboss.com/wiki/Wiki.jsp?page=JBossSeam

                                    I hope you find this useful.
                                    Matthew