14 Replies Latest reply on Jan 23, 2016 1:10 AM by Alexander Minchev

    j_security_check & Struts

    Tim McGinnis Newbie

      I am trying to use a form based login and I am rather confused.

      I have been trolling through the forums here and elsewhere, read the jaas howto at least twice, read the security parts of the Servlet 2.3 and J2EE specs and the thing I cannot figure how to do is use the j_security_check with struts!

      Is j_security_check a function/module/method/page/whatever in tomcat? Or is it some slight of hand that I am not understanding?

      How do I map it in the struts-config.xml file?

      What action class would I point the mapping to?

      I saw one place where it said not to use the struts tags for the form elements and the struts you wouldn't have to bother with the mapping. But when I do this 400 error code, invalid path.

      Can someone clear up my muddied waters?

        • 1. Re: j_security_check & Struts
          Tim McGinnis Newbie

          Well, maybe everybody is on vacation.

          If not, and my question is just too stupid to answer, could somebody at least tell me if it is possible to use j_security_check with struts and tiles?

          I am trying to put my login page inside a tiled page and can't seem to get it to work.

          • 2. Re: j_security_check & Struts
            Gerd Streubel Newbie

            Your question isn't stupid, I was dealing with the same problem.

            Is j_security_check a function/module/method/page/whatever in tomcat? Or is it some slight of hand that I am not understanding?

            The action j_security_check is part of the form-based authentication and thus is part of the Servlet spec.

            How do I map it in the struts-config.xml file?

            Not at all. The target j_security_check is handled completely within the Webcontainer.

            What action class would I point the mapping to?

            You cannot catch this event.

            I saw one place where it said not to use the struts tags for the form elements and the struts you wouldn't have to bother with the mapping. But when I do this 400 error code, invalid path.

            When using <html:form action="j_security_check" ...> you have to provide the appropriate mapping otherwise struts will complain about the action. But the configured action gets never called, because the action is handled internally.
            Furthermore I believe, that struts converts the action "j_security_check" to "/j_security_check". This is definitely wrong.
            So, it is better to use <form action="j_security_check" ...>.

            I hope this helps.


            • 3. Re: j_security_check & Struts
              Tim McGinnis Newbie

              Thankyou very much for the re-assurance that I am not going bonkers. What you said verifies everything that I have seen so far. My big problem is that our site is completely set up using tiles. From what I can see to use tiles I MUST use struts, therefore I cannot use j_security_check.

              Is that correct?

              • 4. Re: j_security_check & Struts
                Gerd Streubel Newbie

                I am using completely struts with templates (a kind of tiles) except for the login screen. Because the loginpage is handled by the webcontainer this page is the only one which is written "manually" in html.
                If you cannot go this way you can do the JAAS-authentication by writing a filter. Here is an example by Peter Doornbosch: http://www.luminis.nl/publications/websecurity.html
                This solution has one big disadvantage. The web resources cannot be secured.

                • 5. Re: j_security_check & Struts
                  Gary Cuozzo Newbie

                  I just noticed this thread, and am not really sure what the big issue is. My form based login page is a JSP and uses struts tags and tiles. My form action posts directly to j_security_check.

                  The struts controller servlet does not enter the picture until after the authentication is complete.

                  I think this would be the life cycle for my webapp:
                  1. browser requests /webapp/protectedresource/mainmenu.do
                  2. tomcat redirects to login page which is a jsp page that uses struts tags and tiles
                  3. user logs in. post goes to j_security_check
                  4. container authenticates and loads /webapp/protectedresource/mainmenu.do, which is mapped to the struts controller servlet.
                  5. struts takes over from here, runs the action and forwards to the view.

                  I have my struts controller mapped to *.do in my web.xml.

                  If I'm missing the real issue and this doesn't help let me know. Maybe you are trying to do something additional that I'm not.

                  gary.

                  • 6. Re: j_security_check & Struts
                    Gerd Streubel Newbie

                     

                    My form action posts directly to j_security_check.

                    If the login-form of the loginpage is the only reason for using struts you can also use pure html, because it dosen't matter if the loginpage is made up with struts or with pure html. The struts action will never be called. So if you have additional controls besides "j_username" and "j_password" within your form you will never get these values.
                    But there may be other reasons why you are bound to struts.


                    • 7. Re: j_security_check & Struts
                      tschraepen Newbie

                       

                      "cuoz" wrote:
                      I just noticed this thread, and am not really sure what the big issue is. My form based login page is a JSP and uses struts tags and tiles. My form action posts directly to j_security_check.

                      The struts controller servlet does not enter the picture until after the authentication is complete.

                      I think this would be the life cycle for my webapp:
                      1. browser requests /webapp/protectedresource/mainmenu.do
                      2. tomcat redirects to login page which is a jsp page that uses struts tags and tiles
                      3. user logs in. post goes to j_security_check
                      4. container authenticates and loads /webapp/protectedresource/mainmenu.do, which is mapped to the struts controller servlet.
                      5. struts takes over from here, runs the action and forwards to the view.

                      I have my struts controller mapped to *.do in my web.xml.

                      If I'm missing the real issue and this doesn't help let me know. Maybe you are trying to do something additional that I'm not.

                      gary.


                      I'm aware of the fact that this is kind of late for a follow-up, but this is the only thread (out of the other 20 I've read) that matches my JAAS/Struts problem.

                      That having said, could you post the code for the form of your logon page?

                      The things I don't understand are:
                      1. where do you put your authentication code (the LoginContext lc.login and stuff)?
                      2. if one were to start from a logon-page (opposing to your case, where a user tries to request a secured web-page), how would you suggest forwarding to the correct page after login was succesful?

                      FYI, here's my scenario:

                      I'm using Struts - tags and ActionForms - on every page.
                      The web-application starts with a logon page.
                      Currently I've got a LogonAction which merely checks if the username exists in a database (through an EJB layer), and if it does, forward to the main-page.
                      I tried using FORM authentication like this:

                      --- In login-config.xml ---
                      <application-policy name="ReqPoster">
                       <authentication>
                       <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                       flag="required">
                       <module-option name="usersProperties">ReqPoster-users.properties</module-option>
                       <module-option name="rolesProperties">ReqPoster-roles.properties</module-option>
                       </login-module>
                       </authentication>
                       </application-policy>
                      


                      I keep the usersProperties.properties and the rolesProperties.properties files in the web.war 's /WEB-INF/classes/ directory. (Where is that defined anyway, I didn't know for sure until recently when I read some posts)

                      --- In web.xml ---
                      <login-config>
                       <auth-method>FORM</auth-method>
                       <realm-name>ReqPoster</realm-name>
                      
                       <form-login-config>
                       <form-login-page>/pages/login.jsp</form-login-page>
                       <form-error-page>/pages/error.jsp</form-error-page>
                       </form-login-config>
                      
                      </login-config>
                      
                      <security-constraint>
                       <web-resource-collection>
                       <web-resource-name>ReqPosterWeb</web-resource-name>
                      <url-pattern>*.do</url-pattern>
                       </web-resource-collection>
                       <auth-constraint>
                      <role-name>UserRole</role-name>
                      <role-name>AdminRole</role-name>
                       </auth-constraint>
                      </security-constraint>
                      


                      --- In login.jsp ---
                      <html:form action="actions/login.do" method="post">
                      
                      <div class="formbox">
                       <p>
                       <label for="j_username"><bean:message key="login.userPrompt" /></label><html:text styleClass="mainInput" property="j_username" styleId="user" onfocus="inputIn(this.id);" onblur="inputOut(this.id);" />
                       </p>
                       <p>
                       <label for="j_password"><bean:message key="login.passwordPrompt" /></label><html:password redisplay="false" styleClass="mainInput" property="j_password" styleId="pass" onfocus="inputIn(this.id);" onblur="inputOut(this.id);"/>
                       </p>
                       <p>
                       <label> </label><input type="submit" id="submit" value='<bean:message key="login.submitLabel" />' />
                       </p>
                      </div>
                      
                      </html:form>
                      


                      I've got my actionform set to accept these values, but the logonAction does not redirect to the j_security_check.
                      Instead I've got this in a filter:

                       public void init(FilterConfig filterConfig) throws ServletException {
                       this.filterConfig = filterConfig;
                       System.out.println("AuthenticationFilter.init()");
                       configName = filterConfig.getInitParameter("configName");
                       username = filterConfig.getInitParameter("username");
                       String x = filterConfig.getInitParameter("password");
                       if( x != null )
                       password = x.toCharArray();
                       handler = new UsernamePasswordHandler(username, password);
                       }
                      
                       public void doFilter(
                       ServletRequest request,
                       ServletResponse response,
                       FilterChain chain) throws IOException, ServletException {
                       LoginContext lc = null;
                       try {
                       System.out.println("AuthenticationFilter, login as: "+username);
                       lc = new LoginContext(configName, handler);
                       lc.login();
                       } catch(LoginException e) {
                       throw new ServletException("Failed to perform JAAS login", e);
                       }
                       try {
                       chain.doFilter(request, response);
                       } finally {
                       if( lc != null ) {
                       try{
                       System.out.println("AuthenticationFilter, logout");
                       lc.logout();
                       } catch(LoginException e) {
                       e.printStackTrace();
                       }
                       }
                       }
                       }
                      


                      --- Filter statements in web.xml ---
                       <filter>
                       <filter-name>AuthenticationFilter</filter-name>
                       <display-name>AuthenticationFilter</display-name>
                       <description><![CDATA[Checks if a session is authenticated.]]></description>
                       <filter-class>org.ineos.RequestPosterAdmin.filters.AuthenticationFilter</filter-class>
                       <init-param>
                       <param-name>configName</param-name>
                       <param-value>ReqPoster</param-value>
                       </init-param>
                       <init-param>
                       <param-name>username</param-name>
                       <param-value>test</param-value>
                       </init-param>
                       <init-param>
                       <param-name>password</param-name>
                       <param-value>ptest</param-value>
                       </init-param>
                       </filter>
                      
                      
                       <filter-mapping>
                       <filter-name>AuthenticationFilter</filter-name>
                       <url-pattern>*.do</url-pattern>
                       </filter-mapping>
                      


                      If I comment out the login-config elements in web.xml and use BASIC authentication instead of FORM, it does work. Now all it does is redirect the user back to the login page.

                      What I'm looking for is
                      1. to be able to use the form authentication
                      2. getting the user and her roles for further authorization in the future (in Struts Actions), by using the .isUserInRoles and stuff like that.

                      Any help would be greatly appreciated.

                      P.S.: My apologies for this late follow-up.

                      • 8. Re: j_security_check & Struts
                        Gary Cuozzo Newbie

                        It sounds like you are quite close on this. I think your problem should be pretty easy to fix. To answer your questions:
                        1. I don't have any authentication code at all in my webapp. The j_security_check sets up the context for you. I don't use a struts-form for my login. Do this: Use a straight-up html/jsp page and don't post to a struts action. Post the j_security_check. That should be all you need. By posting to your logon action, you are bypassing the container security code that would set all security context for you.

                        2. You should not reference your login page or the the j_security_check directly. You should only allow the web container to redirect you to it as necessary. I think you will get exceptions or http error codes back if you try to force this. The container will handle it all for you. To logout, I have a logout action that checks for a valid session and if there is one, invalidates it.

                        Do that and let me know if you still need further help.
                        gary.

                        • 9. Re: j_security_check & Struts
                          tschraepen Newbie

                          Thanks for the quick reply Cuoz.

                          I'm beginning to understand what the actual problem is with my web-app.
                          You see, I've been mixing the j_security_check and a self-written JAAS authentication method.
                          j_security_check however, doesn't provide the solution I'm looking for.
                          Because it doesn't integrate with a struts environment. I would have to code a Servlet separate from struts for the building of the web-app so to say. And have struts handle the rest of the workflow.
                          I'm going to read some more about JAAS authentication, I think I was on the right track with the filter.

                          As for the logout action, I've noticed that if I just invalidate the session, the server will create a new one when the user presses the "back"-button. I solved that issue with another filter which checks if a user has credentials (just for now, but I will make it more secure with time). And I remove those credentials with the logoutAction. But that's kind of off-topic here :)

                          Anyway, thanks again. You've helped me back on track.

                          • 10. Re: j_security_check & Struts
                            Gary Cuozzo Newbie

                            I'm just curious (for my own knowledge) what kind of integration with struts you are looking for? I broke my app into multiple struts modules, each one has an associated role that is required to access it. It is fairly simple and works well.

                            For the logout, yes, when they hit the server again, they will get a new session. But, they will still need to authenticate again. For my app, this is fine.

                            • 11. Re: j_security_check & Struts
                              tschraepen Newbie

                              I've done a couple of things since my last post:

                              1. Moved my loginAction to path /login.do instead of /actions/login.do, so that I can use an url-pattern on /actions/* for my filter.
                              2. Added JAAS login to that filter.
                              It's still not working though, logging in refers me to the index page. But when I request a page that uses an action, I get redirected to the login page again. I think this is because the security constraint precedes the filter's actions, and the JAAS login is never done.
                              Now I'm going to check if the cause is the CallBackHandler. I'm following this example: http://www.mooreds.com/jaas.html#AEN162.

                              I feel I'm closer to the solution by implementing a JAAS login myself, than using the j_security_check.
                              It would also be better for future purposes, because I'm kind of building this application as a technology testing assignment. And the idea is to make a Swing GUI for the application as well, by reusing as much code as possible. I was thinking I could reuse JAAS.

                              • 12. Re: j_security_check & Struts
                                tschraepen Newbie

                                But I'm still interested in your setup Cuoz.
                                Could you post a part of your login.jsp, struts-config.xml and web.xml?

                                • 13. Re: j_security_check & Struts
                                  Nikolaos Abatzis Newbie

                                  Did you ever get the files, login.jsp,struts....

                                  Can you share them?

                                  • 14. Re: j_security_check & Struts
                                    Alexander Minchev Newbie

                                    Hope it is not too late :-)

                                     

                                    - yes, it is possible!

                                     

                                    I had to deal with the same issue recently, and here are the results:

                                     

                                    https://alex4java.wordpress.com/2016/01/23/form-based-authentication-with-struts-1-1/