6 Replies Latest reply on Nov 23, 2006 10:51 AM by cavani

    JaasAuthenticationProvider in Seam 1.1

    fcorneli

      I would like to use my JAAS login module in my Seam-based application to protect some of the Seam EJB3 backing beans via EJB3 RBAC. I see that Seam 1.1 has a JaasAuthenticationProvider for this. How to use it? Looking at the source code of Seam 1.1.0.CR1 I wonder whether this thing already works with that much code commented out...

        • 1. Re: JaasAuthenticationProvider in Seam 1.1
          pmuir

          I'm pretty sure the Seam security stuff isn't ready yet - see the roadmap for details of upcoming stuff in Seam.

          • 2. Re: JaasAuthenticationProvider in Seam 1.1
            gavin.king

            Its definitely not ready. It is scheduled for 1.1.5 in early Jan.

            • 3. Re: JaasAuthenticationProvider in Seam 1.1
              cavani

              I use, since Seam 1.0.CR3, a dirty but cheap solution (I will wait for a clean one with 1.1.5).

              I mixed this:

              http://groundside.com/blog/DuncanMills.php?title=j2ee_security_a_jsf_based_login_form

              and JAAS example on Seam Wiki (http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossSeam)

              long story short (this is not complete but show the idea - I can complete if there is interest) :

              sidebar for Login.xhtml on /WEB-INF/sidebar/Login.xhtml (based on DVD Store example):

              <c:choose xmlns="http://www.w3.org/1999/xhtml"
               xmlns:ui="http://java.sun.com/jsf/facelets"
               xmlns:f="http://java.sun.com/jsf/core"
               xmlns:h="http://java.sun.com/jsf/html"
               xmlns:c="http://java.sun.com/jstl/core">
              
               <c:when test="#{ currentUser == null }">
               <div class="sidebarWrapper">
               <dl>
               <dt class="sidebarHeader">Login</dt>
               <dd class="sidebarForm">
               <h:form id="loginForm">
               <dl>
               <dt><h:outputText value="Usuário"/></dt>
               <dd><h:inputText id="j_username" value="#{ login.username }" size="16" styleClass="text"/></dd>
               <dt><h:outputText value="Senha"/></dt>
               <dd><h:inputSecret id="j_password" value="#{ login.password }" size="16" styleClass="text"/></dd>
              
               <dd>
               <h:commandButton action="#{ login.login }" value="Entrar" styleClass="formButton" style="width: 166px;"/>
               </dd>
               <dd><h:messages globalOnly="true"/></dd>
               </dl>
               </h:form>
               </dd>
               </dl>
               </div>
               </c:when>
              
               <c:otherwise>
               <div class="sidebarWrapper">
               <dl>
               <dt class="sidebarHeader">Bem-vindo, #{ currentUser.nickname }</dt>
               <dd class="sidebarForm">
               <h:form>
               <dl>
               <dd>Seu acesso está autorizado</dd>
               <dd>
               <h:commandButton action="#{ login.logout }" value="Logout" class="formButton" style="width: 166px;"/>
               </dd>
               </dl>
               </h:form>
               </dd>
               </dl>
               </div>
               </c:otherwise>
              
              </c:choose>
              


              Login Action Bean:

               public String login()
               {
              
               String username = this.username;
               String password = this.password;
              
               this.username = null;
               this.password = null;
              
               try
               {
               UserReference user = (UserReference) em.createQuery("from UserReference u where u.username = :username and u.password = :password")
               .setParameter("username", username)
               .setParameter("password", password)
               .getSingleResult();
              
              
               Contexts.getSessionContext().set("currentUser", user);
               Contexts.getSessionContext().set("loggedIn", true);
              
               // PUT HERE CONTEXT USER RELATED CONTENT
              
               ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
              
               HttpServletRequest request = (HttpServletRequest)ectx.getRequest();
               HttpServletResponse response = (HttpServletResponse)ectx.getResponse();
              
               RequestDispatcher dispatcher = request.getRequestDispatcher("loginProxy.jsp");
               dispatcher.forward(request, response);
              
               return null;
              
               }
               catch (Exception e)
               {
               FacesMessages.instance().add("Erro de Login");
               return null;
               }
               }
              
               public String logout()
               {
               Seam.invalidateSession();
               Contexts.getSessionContext().set("currentUser", null);
               Contexts.getSessionContext().set("loggedIn", null);
               return "index";
               }
              


              For real JAAS pass in loginProxy.jsp:

              <?xml version="1.0" encoding="UTF-8" ?>
              <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
               <jsp:directive.page language="java"
               contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" />
               <jsp:text>
               <![CDATA[ <?xml version="1.0" encoding="UTF-8" ?> ]]>
               </jsp:text>
               <jsp:text>
               <![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ]]>
               </jsp:text>
              <html xmlns="http://www.w3.org/1999/xhtml">
              <head>
               <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
               <title>Logging in</title>
              </head>
              <body onload="document.forms[0].submit()">
              
               Você está sendo redirecionado... Por favor aguarde!<br/>
               Caso seu browser não esteja carregando a página, tente novamente!
               <br/><br/>
               Atenciosamente,<br/>
               Equipe de Desenvolvimento da Uqbar
              
               <form method="post" action="j_security_check">
               <input type="hidden" name="j_username" value='${ param["loginForm:j_username"] }' />
               <input type="hidden" name="j_password" value='${ param["loginForm:j_password"] }' />
               </form>
              </body>
              </html>
              </jsp:root>
              


              worth mention web.xml (I use .html instead of .seam):

               <!-- JAAS -->
              
               <security-constraint>
               <web-resource-collection>
               <web-resource-name>Ipanema</web-resource-name>
               <description>Intranet Information Manager</description>
               <url-pattern>/Index.html</url-pattern>
               <url-pattern>/Management/*</url-pattern>
               <url-pattern>/QueryTool/*</url-pattern>
               <url-pattern>/Data/*</url-pattern>
               <http-method>POST</http-method>
               <http-method>GET</http-method>
               </web-resource-collection>
               <auth-constraint>
               <description>Acesso Controlado de Usuários</description>
               <role-name>ADMINISTRATORS</role-name>
               <role-name>USERS</role-name>
               </auth-constraint>
               </security-constraint>
              
              
               <login-config>
               <auth-method>FORM</auth-method>
               <form-login-config>
               <form-login-page>/Login.html</form-login-page>
               <form-error-page>/Login.html</form-error-page>
               </form-login-config>
               </login-config>
              
              
               <security-role>
               <description>Administrador</description>
               <role-name>ADMINISTRATORS</role-name>
               </security-role>
              
               <security-role>
               <description>Usuários Comuns</description>
               <role-name>USERS</role-name>
               </security-role>
              


              And login base page referenced by web.xml:

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml"
               xmlns:ui="http://java.sun.com/jsf/facelets">
              
              <body>
               <ui:composition template="/WEB-INF/base/MasterPage.xhtml">
              
               <ui:define name="sidebar">
               <ui:include src="/WEB-INF/sidebar/Login.xhtml"/>
               </ui:define>
              
               <ui:define name="content">
              
               <h1>Bem Vindo ao Ipanema</h1>
              
               </ui:define>
              
               </ui:composition>
              </body>
              
              </html>
              



              I use this on JBoss AS 4.0.5 and

              • 4. Re: JaasAuthenticationProvider in Seam 1.1
                cavani

                [I forgot]

                I use this on JBoss AS 4.0.5.GA now, but started with 4.0.4.GA.

                I could not use version 2.5 on web.xml... some problem with EL on JSP (I am using Seam EL), but I think this was a Seam bug that is fixed now...

                I don't answer your question but hope this help someone...

                • 5. Re: JaasAuthenticationProvider in Seam 1.1
                  fcorneli

                  Using a forward to a native j_security_check is indeed an easy way to use the servlet container provided security features. But on the other hand, you're mixing JSF with non-JSF stuff. I was more thinking of using a servlet filter to do the client-login into the security domain when the username and password has been set on the session as attributes. That way the error reporting on a failed login "stays within JSF". Any suggestions here?

                  • 6. Re: JaasAuthenticationProvider in Seam 1.1
                    cavani

                    I do any authentication/authorization on login method of an Seam Component loginAction (beside JAAS module), then, the error control and other user related context is load that place... JSP is just used to confirm user authentication through JAAS (JAAS and loginAction use the same database then no rush)....

                    Like I sad, this is dirty but cheap.... almost no Java code (5 lines for redirect to JSP) and using AS security features... I hope improve this easily when Seam Security Framework will be available.

                    Just my two cents...

                    Thanks,