5 Replies Latest reply on Jan 19, 2009 2:47 PM by ssilvert

    JSFUnit and security

    wolfgangknauf

      Hi Stan,

      two things:
      the first is an easy one: the doc at http://www.jboss.org/community/docs/DOC-10974 is outdated for "Testing with FORM authentication". as the code snippet does not compile any longer.
      It should be:

      WebClientSpec wcSpec = new WebClientSpec("/mysecurepage.jsf");
      FormAuthenticationStrategy formAuth = new FormAuthenticationStrategy("username", "password", "login_button");
      wcSpec.setInitialRequestStrategy(formAuth);


      And now to the real problem:
      How to log out? I tried to do it by clicking the logout button in the test method:
      this.client.click("formlogout:logout");

      This resulted in this exception:

      getAttribute: Session already invalidated
      
      java.lang.IllegalStateException: getAttribute: Session already invalidated
      at org.apache.catalina.session.StandardSession.getAttribute(StandardSession.java:1032)
      at org.apache.catalina.session.StandardSessionFacade.getAttribute(StandardSessionFacade.java:110)
      at org.jboss.jsfunit.framework.FacesContextBridge.getCurrentInstance(FacesContextBridge.java:56)
      at org.jboss.jsfunit.jsfsession.JSFServerSession.pageCreated(JSFServerSession.java:167)
      at org.jboss.jsfunit.jsfsession.JSFServerSession.afterRequest(JSFServerSession.java:188)
      at org.jboss.jsfunit.framework.JSFUnitWebConnection.notifyListenersAfter(JSFUnitWebConnection.java:103)
      at org.jboss.jsfunit.framework.JSFUnitWebConnection.getResponse(JSFUnitWebConnection.java:84)
      at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1487)
      at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1445)
      at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:323)
      at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:352)
      at com.gargoylesoftware.htmlunit.html.HtmlForm.submit(HtmlForm.java:171)
      at com.gargoylesoftware.htmlunit.html.HtmlSubmitInput.doClickAction(HtmlSubmitInput.java:78)
      at com.gargoylesoftware.htmlunit.html.ClickableElement.click(ClickableElement.java:148)
      at com.gargoylesoftware.htmlunit.html.ClickableElement.click(ClickableElement.java:107)
      at com.gargoylesoftware.htmlunit.html.ClickableElement.click(ClickableElement.java:76)
      at org.jboss.jsfunit.jsfsession.JSFClientSession.click(JSFClientSession.java:223)
      at de.fhw.komponentenarchitekturen.knauf.security.test.SecurityTest.testSecurity(SecurityTest.java:70)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at org.apache.cactus.internal.AbstractCactusTestCase.runBareServer(AbstractCactusTestCase.java:153)
      at org.apache.cactus.internal.server.AbstractWebTestCaller.doTest(AbstractWebTestCaller.java:119)
      at org.apache.cactus.internal.server.AbstractWebTestController.handleRequest_aroundBody0(AbstractWebTestController.java:93)
      at org.apache.cactus.internal.server.AbstractWebTestController.handleRequest_aroundBody1$advice(AbstractWebTestController.java:224)
      at org.apache.cactus.internal.server.AbstractWebTestController.handleRequest(AbstractWebTestController.java)
      at org.apache.cactus.server.ServletTestRedirector.doPost_aroundBody2(ServletTestRedirector.java:101)
      at org.apache.cactus.server.ServletTestRedirector.doPost_aroundBody3$advice(ServletTestRedirector.java:217)
      at org.apache.cactus.server.ServletTestRedirector.doPost(ServletTestRedirector.java)
      at org.jboss.jsfunit.framework.JSFUnitServletRedirector.doPost(JSFUnitServletRedirector.java:46)
      at org.apache.cactus.server.ServletTestRedirector.doGet_aroundBody0(ServletTestRedirector.java:72)
      at org.apache.cactus.server.ServletTestRedirector.doGet_aroundBody1$advice(ServletTestRedirector.java:217)
      at org.apache.cactus.server.ServletTestRedirector.doGet(ServletTestRedirector.java)
      at org.jboss.jsfunit.framework.JSFUnitServletRedirector.doGet(JSFUnitServletRedirector.java:52)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.jboss.jsfunit.framework.JSFUnitFilter.doFilter(JSFUnitFilter.java:116)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
      at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
      at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
      at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Unknown Source)


      Thanks

      Wolfgang

        • 1. Re: JSFUnit and security
          wolfgangknauf

          I should have given more details...

          Clicking the logout button "formlogout:logout" calls a page "logout.jsp", which has mainly this content:

          <%
           session.invalidate();
          %>
          You were logged out.


          I did not find any method in the JSFUnit framework which seems to be able to end the session.

          Thanks

          Wolfgang

          • 2. Re: JSFUnit and security
            ssilvert

            JSFUnit protects session.invalidate() because it uses the session as a conduit between JSF and your tests. During a test, JSFUnit will wrap the HttpSession so that HttpSession.invalidate() will merely remove all attributes not used by JSFUnit. The problem is that you got the JSP implicit HttpSession object, which JSFUnit can't wrap.

            As long as your "logged out" page is a JSF page and you get the HttpSession from the ExternalContext then it should work with JSFUnit. So you could re-write your JSP like this and it should work.

            <%
            ExternalContext extCtx = FacesContext.getCurrentInstance().getExternalContext();
            HttpSession session = (HttpSession)extCtx.getSession();
            session.invalidate();
            %>


            Stan

            • 3. Re: JSFUnit and security
              wolfgangknauf

              Hi Stan,

              thanks, this works now without errors.

              As others might run into the same question, here are two minor updates:
              a) the code snippet should be:

              <%
               ExternalContext extCtx = FacesContext.getCurrentInstance().getExternalContext();
               HttpSession sessionHttp = (HttpSession)extCtx.getSession(false);
               sessionHttp.invalidate();
              %>

              ("getSession" has a parameter, and a variable named "session" is not allowed).

              b) this snippet must follow the closing </f:view> tag. Otherwise this will raise an JSF exception.

              Could you add this information to the "JSFUnitTestingSecurePages" wiki page?

              I saw that you corrected the "FORM authentication" section. But the last sentence of it ("...If you do not call formAuth.setSubmitComponent(), it will default to "Submit".") still points to outdated API.

              Thanks

              Wolfgang

              • 4. Re: JSFUnit and security
                ssilvert

                I'll make those changes. Thanks for pointing them out.

                In the future, feel free to make wiki changes yourself. I'll get a notification, so I can see what was done.

                Stan

                • 5. Re: JSFUnit and security
                  ssilvert

                  Changes are done.

                  ExternalContext.getSession(false) can return null. You should say:

                  if (sessionHttp != null) sessionHttp.invalidate();


                  Stan