11 Replies Latest reply on May 7, 2014 12:32 AM by renannp

    FORM authentication issues

    renannp

      Hi.

       

      I've been trying to get logout to work for few weeks already and I couldn't figure out where is the problem.

      I'm about to think that this is a bug of Wildfly, but maybe I'm doing something wrong, so here it goes.

       

      Browser: Chrome 33.0.1750.154 m

      JDK Version:

      java version "1.7.0_45"

      Java(TM) SE Runtime Environment (build 1.7.0_45-b18)

      Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

      Wildfly Version: WildFly 8.0.0.Final

       

      What I'm trying to do should be pretty basic. I try to login, to access a protected url pattern, then I logout and even after logout I try to access the protected url again with success.

      So here it follows the requests/responses of this flow.

       

      1 - Login

       

      Request URL:http://localhost:8080/repbill/j_security_check

      Request Method:POST

      Status Code:200 OK

      Request Headersview source

      Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

      Accept-Encoding:gzip,deflate,sdch

      Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4

      Cache-Control:max-age=0

      Connection:keep-alive

      Content-Length:46

      Content-Type:application/x-www-form-urlencoded

      Host:localhost:8080

      Origin:http://localhost:8080

      Referer:http://localhost:8080/repbill/

      User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36

      Form Dataview sourceview URL encoded

      j_username:renann

      j_password:123

      submit:submit

      Response Headersview source

      Connection:keep-alive

      Content-Length:0

      Date:Wed, 09 Apr 2014 14:40:39 GMT

      Server:Wildfly 8

      Set-Cookie:JSESSIONID=yM_dHllWkZsfWHdh1R-zExHH.copaim6578; path=/repbill

      X-Powered-By:Undertow 1

       

      Possible issue: Instead of being redirected to the protected url which I'm allowed, I get redirected to repbill/j_security_check, which makes no sense for me.

       

      2 - I try to access the protected url, by accessing its root path /repbill/protected

       

      Request URL:http://localhost:8080/repbill/protected/

      Request Method:GET

      Status Code:200 OK

      Request Headersview source

      Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

      Accept-Encoding:gzip,deflate,sdch

      Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4

      Connection:keep-alive

      Cookie:JSESSIONID=yM_dHllWkZsfWHdh1R-zExHH.copaim6578

      Host:localhost:8080

      User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36

      Response Headersview source

      Connection:keep-alive

      Content-Length:333

      Content-Type:text/html

      Date:Wed, 09 Apr 2014 14:41:29 GMT

      Last-Modified:Tue, 08 Apr 2014 19:13:00 GMT

      Server:Wildfly 8

      X-Powered-By:Undertow 1

       

      3 - I try to do logout, and get redirected to the /repbill, which is expected

       

      Request URL:http://localhost:8080/repbill/logout

      Request Method:GET

      Status Code:302 Found

      Request Headersview source

      Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

      Accept-Encoding:gzip,deflate,sdch

      Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4yM_dHllWkZsfWHdh1R

      Connection:keep-alive

      Cookie:JSESSIONID=yM_dHllWkZsfWHdh1R-zExHH.copaim6578

      Host:localhost:8080

      Referer:http://localhost:8080/repbill/protected/

      User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36

      Response Headersview source

      Cache-Control:no-cache, no-store

      Connection:keep-alive

      Content-Length:0

      Date:Wed, 09 Apr 2014 14:41:48 GMT

      Expires:Wed Apr 09 11:41:48 BRT 2014

      Location:http://localhost:8080/repbill

      Pragma:no-cache

      Server:Wildfly 8

      Set-Cookie:JSESSIONID=-zExHH.copaim6578; path=/repbill; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:00 GMT

      X-Powered-By:Undertow 1

       

      4 - Then I try to access the /repbill/protected url pattern again, with success. Although it seems to be from the cache, I believe that it shouldn't work this way.

       

      Request URL:http://localhost:8080/repbill/protected/

      Request Method:GET

      Status Code:200 OK (from cache)

       

      5 - If I try to access the /protected/index.html, I get redirected to the /repbill. But the URL is still repbill/protected/index.html

       

      Request URL:http://localhost:8080/repbill/protected/index.html

      Request Method:GET

      Status Code:200 OK

      Request Headersview source

      Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

      Accept-Encoding:gzip,deflate,sdch

      Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4

      Connection:keep-alive

      Host:localhost:8080

      User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36

      Response Headersview source

      Connection:keep-alive

      Content-Length:756

      Content-Type:text/html

      Date:Wed, 09 Apr 2014 14:43:05 GMT

      Last-Modified:Tue, 08 Apr 2014 16:08:40 GMT

      Server:Wildfly 8

      Set-Cookie:JSESSIONID=exOaSwIVg0yK0k7KHYzurRcF.copaim6578; path=/repbill

      X-Powered-By:Undertow 1

       

      Here follows my configuration:

       

      web.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
          <security-constraint>
              <display-name>Security Constraint Display Test Display Name</display-name>
              <web-resource-collection>
                  <web-resource-name>Protected Area</web-resource-name>
                  <url-pattern>/protected/*</url-pattern>
                  <http-method>GET</http-method>
                  <http-method>HEAD</http-method>
                  <http-method>POST</http-method>
                  <http-method>PUT</http-method>
                  <http-method>DELETE</http-method>
                  <http-method>CONNECT</http-method>
                  <http-method>OPTIONS</http-method>
                  <http-method>TRACE</http-method>
              </web-resource-collection>
              <auth-constraint>
                  <role-name>OWNER</role-name>
              </auth-constraint>
              <user-data-constraint>
                  <!-- TODO: try to change to CONFIDENTIAL or INTEGRAL, reffer to web-common_3_1.xsd -->
                  <transport-guarantee>NONE</transport-guarantee>
              </user-data-constraint>
          </security-constraint>
          <login-config>
              <auth-method>FORM</auth-method>
              <realm-name>example-jaas-realm</realm-name>
              <form-login-config>
                  <form-login-page>/index.html</form-login-page>
                  <form-error-page>/error.html</form-error-page>
              </form-login-config>
          </login-config>
          <session-config>
              <session-timeout>
                  30
              </session-timeout>
          </session-config>
          <welcome-file-list>
              <welcome-file>index.html</welcome-file>
          </welcome-file-list>
          <security-role>
              <role-name>OWNER</role-name>
          </security-role>
          <error-page>
              <error-code>404</error-code>
              <location>/404.html</location>
          </error-page>
          <error-page>
              <error-code>403</error-code>
              <location>/403.html</location>
          </error-page> 
      </web-app>
      
      
      
      

       

      jboss-web.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss-web
          xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
          xmlns:ns1='http://www.jboss.com/xml/ns/javaee'
          xsi:schemaLocation='http://www.jboss.com/xml/ns/javaee jboss-web_8_0.xsd'>
      
          <security-domain>example-jaas-realm</security-domain>
      </jboss-web>
      
      
      
      

       

      Security Domain inside standalone.xml

       

      <security-domain name="example-jaas-realm" cache-type="default">
        <authentication>
        <login-module code="Database" flag="required">
        <module-option name="dsJndiName" value="java:jboss/datasources/MySQLDataSource"/>
        <module-option name="principalsQuery" value="select Password from principalsQuery where email like ?"/>
        <module-option name="rolesQuery" value="select groupName, Roles from rolesQuery where memberID in (select m.ID from tb_member m where email like ?)"/>
        </login-module>
        </authentication>
      </security-domain>
      
      
      
      

       

      LogoutServlet.java

       

      protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException
          {
              response.setHeader("Cache-Control", "no-cache, no-store");
              response.setHeader("Pragma", "no-cache");
              response.setHeader("Expires", new Date().toString());
           
              HttpSession session = request.getSession(false);
           
              System.out.println("--- Before logout ---");
              System.out.println("Session ID is " + (request.isRequestedSessionIdValid() ? "valid" : "invalid"));
           
              if (session != null)
              {
                  session.invalidate();
                  System.out.println("Invalidate has been called");
              }
           
              request.logout();     
           
              System.out.println("--- After logout ---");
              System.out.println("Session ID is " + (request.isRequestedSessionIdValid() ? "valid" : "invalid"));
           
              response.sendRedirect("/repbill");
          }
      
      
      
      

       

      /repbill/protected/index.html

       

      <!DOCTYPE html>
      <html>
          <head>
              <title>TODO supply a title</title>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
          </head>
          <body>
              <h1>Pagina Protegida</h1>
            
              <a href="/repbill/logout">Logout</a>
          </body>
      </html>
      
      
      


      /repbill/index.html

       

      <!DOCTYPE html>
      <html>
          <head>
              <title>RepBill 2.0</title>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
          </head>
          <body>
              <h1 style="text-align: center">RepBill 2.0</h1>
      
      
              <form action="j_security_check" method="post">
                  username : <input type="text" name="j_username"/><br>
                  password : <input type="password" name = "j_password"/><br>
                  <input type ="submit" name = "submit" value = "submit">
              </form>
          </body>
      </html>
      
      
      

       

      server.log of the above flow

       

      2014-04-09 13:21:47,645 TRACE [org.jboss.security] (default task-1) PBOX000354: Setting security roles ThreadLocal: null

      2014-04-09 13:22:22,208 TRACE [org.jboss.security] (default task-2) PBOX000200: Begin isValid, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@c84b3766, cache entry: null

      2014-04-09 13:22:22,209 TRACE [org.jboss.security] (default task-2) PBOX000209: defaultLogin, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@c84b3766

      2014-04-09 13:22:22,223 TRACE [org.jboss.security] (default task-2) PBOX000221: Begin getAppConfigurationEntry(example-jaas-realm), size: 4

      2014-04-09 13:22:22,244 TRACE [org.jboss.security] (default task-2) PBOX000224: End getAppConfigurationEntry(example-jaas-realm), AuthInfo: AppConfigurationEntry[]:

      [0]

      LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule

      ControlFlag: LoginModuleControlFlag: required

      Options:

      name=principalsQuery, value=select Password from principalsQuery where email like ?

      name=dsJndiName, value=java:jboss/datasources/MySQLDataSource

      name=rolesQuery, value=select groupName, Roles from rolesQuery where memberID in (select m.ID from tb_member m where email like ?)

       

       

      2014-04-09 13:22:22,263 TRACE [org.jboss.security] (default task-2) PBOX000236: Begin initialize method

      2014-04-09 13:22:22,264 TRACE [org.jboss.security] (default task-2) PBOX000262: Module options [dsJndiName: java:jboss/datasources/MySQLDataSource, principalsQuery: select Password from principalsQuery where email like ?, rolesQuery: select groupName, Roles from rolesQuery where memberID in (select m.ID from tb_member m where email like ?), suspendResume: true]

      2014-04-09 13:22:22,265 TRACE [org.jboss.security] (default task-2) PBOX000240: Begin login method

      2014-04-09 13:22:22,275 TRACE [org.jboss.security] (default task-2) PBOX000263: Executing query select Password from principalsQuery where email like ? with username renann

      2014-04-09 13:22:22,671 TRACE [org.jboss.security] (default task-2) PBOX000241: End login method, isValid: true

      2014-04-09 13:22:22,672 TRACE [org.jboss.security] (default task-2) PBOX000242: Begin commit method, overall result: true

      2014-04-09 13:22:22,672 TRACE [org.jboss.security] (default task-2) PBOX000263: Executing query select groupName, Roles from rolesQuery where memberID in (select m.ID from tb_member m where email like ?) with username renann

      2014-04-09 13:22:22,674 TRACE [org.jboss.security] (default task-2) PBOX000263: Executing query select groupName, Roles from rolesQuery where memberID in (select m.ID from tb_member m where email like ?) with username renann

      2014-04-09 13:22:22,860 TRACE [org.jboss.security] (default task-2) PBOX000210: defaultLogin, login context: javax.security.auth.login.LoginContext@4a6b817f, subject: Subject(1904540281).principals=org.jboss.security.SimplePrincipal@1364744232(renann)org.jboss.security.SimpleGroup@2130957264(Roles(members:MEMBER,OWNER))org.jboss.security.SimpleGroup@2130957264(CallerPrincipal(members:renann))

      2014-04-09 13:22:22,862 TRACE [org.jboss.security] (default task-2) PBOX000207: updateCache, input subject: Subject(1904540281).principals=org.jboss.security.SimplePrincipal@1364744232(renann)org.jboss.security.SimpleGroup@2130957264(Roles(members:MEMBER,OWNER))org.jboss.security.SimpleGroup@2130957264(CallerPrincipal(members:renann)), cached subject: Subject(490754543).principals=org.jboss.security.SimplePrincipal@1364744232(renann)org.jboss.security.SimpleGroup@2130957264(Roles(members:MEMBER,OWNER))org.jboss.security.SimpleGroup@2130957264(CallerPrincipal(members:renann))

      2014-04-09 13:22:22,863 TRACE [org.jboss.security] (default task-2) PBOX000208: Inserted cache info: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@71ca2a11

      2014-04-09 13:22:22,864 TRACE [org.jboss.security] (default task-2) PBOX000201: End isValid, result = true

      2014-04-09 13:22:22,888 TRACE [org.jboss.security] (default task-2) PBOX000354: Setting security roles ThreadLocal: null

      2014-04-09 13:23:22,495 TRACE [org.jboss.security] (default task-3) PBOX000200: Begin isValid, principal: renann, cache entry: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@71ca2a11

      2014-04-09 13:23:22,495 TRACE [org.jboss.security] (default task-3) PBOX000204: Begin validateCache, domainInfo: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@71ca2a11, credential class: class [C

      2014-04-09 13:23:22,495 TRACE [org.jboss.security] (default task-3) PBOX000205: End validateCache, result = true

      2014-04-09 13:23:22,495 TRACE [org.jboss.security] (default task-3) PBOX000201: End isValid, result = true

      2014-04-09 13:23:22,499 TRACE [org.jboss.security] (default task-3) PBOX000354: Setting security roles ThreadLocal: null

      2014-04-09 13:23:26,070 TRACE [org.jboss.security] (default task-4) PBOX000200: Begin isValid, principal: renann, cache entry: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@71ca2a11

      2014-04-09 13:23:26,070 TRACE [org.jboss.security] (default task-4) PBOX000204: Begin validateCache, domainInfo: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@71ca2a11, credential class: class [C

      2014-04-09 13:23:26,070 TRACE [org.jboss.security] (default task-4) PBOX000205: End validateCache, result = true

      2014-04-09 13:23:26,070 TRACE [org.jboss.security] (default task-4) PBOX000201: End isValid, result = true

      2014-04-09 13:23:26,072 INFO  [stdout] (default task-4) --- Before logout ---

       

       

      2014-04-09 13:23:26,073 INFO  [stdout] (default task-4) Session ID is valid

       

       

      2014-04-09 13:23:26,091 INFO  [stdout] (default task-4) Invalidate has been called

       

       

      2014-04-09 13:23:26,092 INFO  [stdout] (default task-4) --- After logout ---

       

       

      2014-04-09 13:23:26,092 INFO  [stdout] (default task-4) Session ID is invalid

       

       

      2014-04-09 13:23:26,093 TRACE [org.jboss.security] (default task-4) PBOX000354: Setting security roles ThreadLocal: null

      2014-04-09 13:23:35,386 TRACE [org.jboss.security] (default task-5) PBOX000354: Setting security roles ThreadLocal: null

       

      So here follows my questions:

       

      1 - Why I get redirected to j_security_check? Is this a configurable behavior or even the correct behavior?

      2 - Why I'm still able to access the protected url after logout? Am I missing something?

      3 - If I clear the browser's cache/cookies (see below img), I can't access the protected url anymore (which is fine). But why the behavior make it seems that the logout didn't work?

       

       

      Thanks

        • 1. Re: FORM authentication issues
          sfcoy

          1 - Why I get redirected to j_security_check? Is this a configurable behavior or even the correct behavior?

           

          Servlet security has always worked this way. The user will be redirected to the login form if they attempt to access a protected resource and are not authorised*. Once authorised the container will return the originally requested resource.

           

          * this means not only authenticated but also in the correct role.

           

          2 - Why I'm still able to access the protected url after logout? Am I missing something?

          The response to http://localhost:8080/repbill/protected/ does not contain the "Cache-Control:no-cache, no-store" headers, so you are getting the cached response and the server never sees the request.

          • 2. Re: Re: FORM authentication issues
            renannp

            Hi, Stephen.


            Thanks for your answer, but perhaps I wasn't clear.

             

            1 - Why I get redirected to j_security_check? Is this a configurable behavior or even the correct behavior?

             

            What I really meant here is: Why I get redirected to j_security_check (even with successful login)? Is this a configurable behavior or even the correct behavior? - see the login request and the red text below it

            To be even more clear:

            1 - I try to login with valid user/pass (and this user has the role with access rights to the /protected)

            2 - After the POST is done, instead of being redirected to the /protected URL, I get redirected to /repbill/j_security_check; which makes me get a blank page (see img below)

             

             

            2 - Why I'm still able to access the protected url after logout? Am I missing something?

            The response to http://localhost:8080/repbill/protected/ does not contain the "Cache-Control:no-cache, no-store" headers, so you are getting the cached response and the server never sees the request.

             

            Before trying to do this request, I did logout - all the steps were done sequentially - and in the logout response you can see the "Cache-Control:no-cache, no-store".

            So even after the logout, I'm still able to access this page from cache, but why? How can I fix this?

             

            Thanks

            • 3. Re: Re: Re: FORM authentication issues
              sfcoy
              1. You should never access the j_security_check URL manually. Always let the container redirect to it. Typically, you would have some sort of home page that is protected so that users are authenticated when they attempt to access it.
              2. " logout response you can see the "Cache-Control:no-cache, no-store" means the logout response will not be cached, not the preceding page. The headers must appear in the response that you do not want cached.
              1 of 1 people found this helpful
              • 4. Re: FORM authentication issues
                renannp

                1 - I'm not trying to directly access the j_security_check. I access the login web page first and after successful login attempt, I get redirected to the "blank page". There's a form which do the POST and I'm using it. I access the login page (which is outside of a secured URL) directly.

                 

                By the way, if you try to directly access the j_security_check, you'll get a 404:

                 

                1. Request URL:http://localhost:8080/repbill/j_security_check
                2. Request Method:GET
                3. Status Code:404 Not Found
                4. Request Headersview source
                  1. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
                  2. Accept-Encoding:gzip,deflate,sdch
                  3. Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4
                  4. Connection:keep-alive
                  5. Host:localhost:8080
                  6. User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
                5. Response Headersview source
                  1. Connection:keep-alive
                  2. Content-Length:1070
                  3. Content-Type:text/html
                  4. Date:Thu, 10 Apr 2014 04:25:32 GMT
                  5. Last-Modified:Wed, 09 Apr 2014 03:58:36 GMT
                  6. Server:Wildfly 8
                  7. X-Powered-By:Undertow 1

                 

                2 - I understand what you say, makes sense for me now. But if I wanted to be redirected to the login page instead of loading the page from cache, what should I do?

                • 5. Re: FORM authentication issues
                  sfcoy

                  My apologies - let me rephrase what I said above:

                  1. You should never access the page containing the login form manually. Always let the container redirect to it. Typically, you would have some sort of home page that is protected so that users are authenticated when they attempt to access it.

                   

                  With respect to the no-cache headers, you should normally apply these to every dynamic page - such as a servlet response or a JSP. The easiest way to do this is in a servlet filter.

                   

                  Assuming that page caching is disabled like this, you will get redirected to the login page as soon as you try to send the user to a protected page.

                  1 of 1 people found this helpful
                  • 6. Re: Re: FORM authentication issues
                    renannp

                    1 - I got it! Thanks! If you could point this anywhere in any documentation, it would be perfect.

                     

                    I've just tried what you've said with the servlet filter, but now the webpages are not being displayed because of the header haha. Is this a good practice at all? Seems more like a workaround.

                     

                    @Override
                        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
                        {
                            String  value = "no-cache";
                            ((HttpServletResponse)response).setHeader("Cache-Control", value);
                        }
                    

                     

                    Thanks

                    • 7. Re: Re: Re: FORM authentication issues
                      sfcoy
                           @Override  
                           public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException  
                           {  
                                String  value = "no-cache";  
                                ((HttpServletResponse)response).setHeader("Cache-Control", value);  
                                chain.doFilter(request, response);
                           }  
                      
                      • 8. Re: Re: Re: FORM authentication issues
                        sfcoy
                        • 9. Re: FORM authentication issues
                          renannp

                          I was facing an issue where my resources (js/css/etc) were also being secured, so I decided to secure certain files - like index.jsp - to fix this. I hope this is the way to go.

                           

                          Thanks a lot!

                          • 10. Re: FORM authentication issues
                            simas_ch

                            I am facing exactly the same problem but only with Chrome browser.

                            With Firefox and IE there is no problem.

                            I don't have dynamic content my pages are static html pages.

                             

                            The application runs on JBoss AS 7 without any problems.

                             

                            Any ideas?    

                            • 11. Re: FORM authentication issues
                              renannp

                              Basically you need to force the user to access a protected context and then it will of course redirect to the login form.

                              After the login, the user will be redirected to the page that the user first tried to access.

                               

                              Hope it helps.