Announcement Announcement Module
Collapse
No announcement yet.
WHy is using multiple <http> elements so hard to configure? [SS 3.1.0.M1] Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • WHy is using multiple <http> elements so hard to configure? [SS 3.1.0.M1]

    I am having a heck of a time getting this to work for this basic test case. I have the following <http> element using <http-basic> that works perfectly.

    Working code:
    Code:
    <http pattern="/sysAdmin/**" use-expressions="true">
    	<intercept-url pattern="/sysAdmin/MainMenu*" access="hasRole('ROLE_ADMIN')"/>
    	<http-basic/>
    	<logout/>
    </http>
    However, I would like to use a "form" login so I tried the following (and many other variations!), but I keep getting a 404 message because it can't find the login page - I believe from pattern matching issues.

    Code:
    <http pattern="/sysAdmin/**" use-expressions="true">
    	<intercept-url pattern="/sysAdmin/MainMenu*" access="hasRole('ROLE_ADMIN')"/>	
    	<intercept-url pattern="/sysAdmin/spring_security_login" access="permitAll"/>	
    	<form-login login-page="/sysAdmin/spring_security_login"/>
    	<logout/>
    </http>
    Browser Error:

    Code:
    HTTP ERROR: 404
    
    NOT_FOUND
    
    RequestURI=/afs/sysAdmin/spring_security_login
    
    Powered by Jetty://
    Anybody have any suggestions? My war file is named afs.war - hence the "/afs/" reference in the RequestURI. However, I didn't think it was necessary to include the base "war path" when pattern matching??

  • #2
    Can you explain why you are using multiple elements? Does it work with just one?

    Comment


    • #3
      I will actually be using 3 <http> elements. I was just trying to set up the "/sysAdmin/**" pattern to see if I could get just one to work. I have three different "areas" in my application in which I would like to set up below...

      1) Main Application, pattern: /app/**, uses /login.jsp to log in with default-target-url=/app/Dashboard.action, remember token valid for 7 days.

      2) Mobile Phone, pattern /mobile/app/**, uses /mobile/login.jsp to log in with default-target-url=/mobile/app/MainMenu.action, remember token 6 months

      3) Admin Pages, pattern /sysAdmin/**, uses default spring_security_login to log in with default-target-url=/sysAdmin/MainMenu.action, no remember me token.

      I was thinking the multiple <http> elements would would work perfectly for this scenario, but am I mistaken on how these are supposed to be used? Otherwise, I assume I need to seperate out the 3 different areas in seperate war files with seperate spring-security settings?

      Thanks for your help!

      Comment


      • #4
        To answer your other question, the code I'm working on now only uses the one <http pattern="/sysAdmin/**"> element. (I tried setting up all three, but was running in to issues, so I am trying to isolate and get the one working). I started with the simplest setup I could think of, but I still get the 404 error on the login page. Then I thought that the default login page was not being matched by the <http> pattern so I changed the form-login line to: <form-login login-page="/sysAdmin/spring_security_login"/>, but still no success.

        Here is the simplest use case I tried, but didn't work...
        Code:
        <http pattern="/sysAdmin/**" use-expressions="true">
        	<intercept-url pattern="/sysAdmin/MainMenu*" access="hasRole('ROLE_ADMIN')"/>	
        	<intercept-url pattern="/**" access="permitAll" />
        	<form-login/>
        	<logout/>
        </http>
        And here's what I get when Spring Sec transfers me to the login page for the settings above...
        Code:
        HTTP ERROR: 404
        NOT_FOUND
        RequestURI=/afs/spring_security_login
        
        Powered by Jetty://
        FYI, if I use a <http> element with no pattern, and place it in a <intercept-url> tag, everything works fine. But of course this won't allow me to set up multiple <http> elements and I'm back where I started using ver. 3.0.4!
        Last edited by burtonrhodes; Oct 28th, 2010, 06:41 AM.

        Comment


        • #5
          The most likely explanation for a 404 is that the page doesn't exist, which is probably what is happening here.

          I wouldn't go overboard with the use of multiple <http> elements - it's mainly intended for situations where configurations are substantially different (for example stateless vs stateful parts of the application). If you are using it then you need to think about how each request is being handled, in particular which security filter chain (if any) it will pass through.

          When you set a pattern on the <http> element, you are specifying that only requests matching that pattern will have the configured filter chain applied. Check the debug logs for information on how a request is matched by the FilterChainProxy.

          In your case you are getting requests for a login page which doesn't exist:

          Case 1. The filter chain only applies to "/sysAdmin/**". You have set

          Code:
          login-page="/sysAdmin/spring_security_login"
          Which is implying that you will create your own login page at this URL. I'm guessing you don't have one so you get a 404.

          Case 2. You revert to using <form-login/>. The default internal login URL is used, but isn't handled by the filter chain, hence you get a 404 again.

          Comment


          • #6
            I understand. That's what I thought might be happening but couldn't figure out a way around it. I guess I'll need to seperate these parts of the web app into different projects. Oh well.

            Thanks for the help!

            Comment


            • #7
              Originally posted by burtonrhodes View Post
              I understand. That's what I thought might be happening but couldn't figure out a way around it. I guess I'll need to seperate these parts of the web app into different projects. Oh well.
              That shouldn't really be necessary. It seems like the only real difference is in the remember-me behaviour for each type. So you can use a single configuration and inject a customized RememberMeServices which adjusts the lifetime of the token based on the user type (or does nothing for admin users).

              For example, if you are using TokenBasedRememberMeServices, extend the class and override the calculateLoginLifetime method. This gives you access to the request and the authentication object for the newly authenticated user, which should be all you need.

              Declare a bean of this type and inject it into the namespace using

              Code:
              <http>
                  <remember-me remember-me-services-ref="yourbean" />
              </http>

              Comment


              • #8
                Sounds good. But how do I account for the different default-target-url locations for each pattern (I also implement always-use-default-target="true") ? What class or method do I override for that?

                Thanks again for all your help.

                Comment


                • #9
                  It is just a URL so you can implement it however you want. For example you could use an MVC controllwer which redirects to the appropriate home page for the user type. Alternatively, implement a custom AuthenticationSuccessHandler.

                  Comment

                  Working...
                  X