Announcement Announcement Module
Collapse
No announcement yet.
use both http-basic and form-login ? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • use both http-basic and form-login ?

    It seems I have to use only either of those. Basically, I would want to divide my app as two apps. One is solely the js/html and the other is restful api.

    Any suggestions ? With the current mechanism I am able to enforce either of form-login or http-basic.

  • #2
    one way I could think of -
    1. deploy the html/js app on apache http server which in turn redirects to the spring based services configured with http-basic.
    What this does is, I can still be able to access restful api say using curl library as well as access by form-login mechanism ? Can some one shed more light on this kind of alternative or mechanism or better architecture ?

    But the question is, how do I transform or maintain credentials ? Is it going to authenticate the http server or the user ?

    Comment


    • #3
      Are you having a specific problem implementing this? I'm not sure I understand your requirements, but I am assuming the only difference is that the RESTful services will use basic authentication and the web application will use a form based login. If this is not the case, can you please clarify?

      Spring supports both basic and form based login at the same time (see the namespace section of the reference for easy setup). The only thing that may complicate things is that when using both the response when not authenticated to your services will be a login page. To fix this I would create an instance of the DelegatingAuthenticationEntryPoint. The instance would have a matcher that finds any request that matches a service call and delegates to BasicAuthenticationEntryPoint. Otherwise it would delegate to LoginUrlAuthenticationEntryPoint.

      Comment


      • #4
        Ok. Here was the original config I had used -
        Code:
        <http auto-config='true' path-type="regex">
        		
        		<intercept-url pattern=".*" access="ROLE_USER" />
        		<form-login login-page="${login.page}" default-target-url="${login.default-target-url}" />		
        		<logout logout-success-url="${logout.success-url}" />
                               <http-basic/> 
        	</http>
        So, what this does is, form-login takes precedence over the http-basic authentication. Whenever a simple request using say poster with auth parameters, is sent, it comes back with a login form.

        I changed it to the following -
        Code:
        
        <beans:bean id="basicAuthenticationFilter"
          class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
          <beans:property name="authenticationManager" ref="authenticationManager"/>
          <beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
        </beans:bean>
        
        <beans:bean id="authenticationEntryPoint"
          class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
          <beans:property name="realmName" value="myApp"/>
        </beans:bean>
        ....
        ....
        <http auto-config='false' path-type="regex">
        		
        		<intercept-url pattern=".*" access="ROLE_USER" />
        		<form-login login-page="${login.page}" default-target-url="${login.default-target-url}" />		
        		<logout logout-success-url="${logout.success-url}" />
                               <http-basic/> 
        	</http>
        As far as I rememb, reading docs, the precedence of the above authenticationfilter was to be set above form-login. However, it seems that was for spring security 2.x. For 3.x it is automatically taken care of (?) !

        Comment


        • #5
          You are correct that when using basic authentication and form based login that the login form will be displayed for unauthenticated users. This is what I was describing in the "only thing that may complicate things" section of my response.

          The configuration appears to be a start at what I had described, but you still need to create a DelegatingAuthenticationEntryPoint and then reference it using entry-point-ref in the http block.

          PS: You don't need to specify auto-config="false" as this is the default.

          Comment


          • #6
            Ok, getting closer. However, reading docs I am not sure, how do I specify to filter out the GET, PUT, POST request ?


            i mean the delegatingauthenticationentrypoint would go like this -
            Code:
             <bean id="daep" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
                 <constructor-arg>
                     <map>
                         <entry key="hasIpAddress('192.168.1.0/24') and hasHeader('User-Agent','Mozilla')" value-ref="firstAEP" />
                         <entry key="hasHeader('User-Agent','MSIE')" value-ref="secondAEP" />
                     </map>
                 </constructor-arg>
                 <property name="defaultEntryPoint" ref="defaultAEP"/>
             </bean>
            do the url filtering go still in the intercept-url portion ? So how does the framework figure out whether to dispatch a form or the http status code for invalid credentials ?

            Comment


            • #7
              Originally posted by rwinch View Post
              You are correct that when using basic authentication and form based login that the login form will be displayed for unauthenticated users. This is what I was describing in the "only thing that may complicate things" section of my response.

              The configuration appears to be a start at what I had described, but you still need to create a DelegatingAuthenticationEntryPoint and then reference it using entry-point-ref in the http block.

              PS: You don't need to specify auto-config="false" as this is the default.
              by http block you meant http-basic block ?

              Comment


              • #8
                No, the http block is where it goes. I'd recommend you use a ecent XML editor which will immediately tell you what attributes are allowed and where, as well as giving you access to the schema documentation. This information is also in the manual.

                Comment


                • #9
                  ok. that looks neat. However, what is <property name="defaultEntryPoint" ref="defaultAEP"/> ??


                  bit confused how that works out or where I'd specify tht.

                  Comment


                  • #10
                    It seems like Luke has already answered most of this, but a few additional comments that may help...

                    Originally posted by muncher View Post
                    Ok, getting closer. However, reading docs I am not sure, how do I specify to filter out the GET, PUT, POST request ?
                    ...
                    do the url filtering go still in the intercept-url portion ? So how does the framework figure out whether to dispatch a form or the http status code for invalid credentials ?
                    The DelegatingAuthenticationEntryPoint will iterate over the keys, which are each a RequestMatcher, in the map passed into it. The first key.matches(HttpServletRequest) that returns true the value will be used as the AuthenticationEntryPoint.

                    If you need to change the AuthenticationEntryPoint based upon http method (I wonder why that would be though) you will need to implement your own RequestMatcher. This is because the ELRequestMatcher does not expose the HttpServletRequest directly. Once you have created your implementation you can place it in the map as a key using standard Spring bean configuration for a map key rather than using the editor (see the Spring Reference for details on how to do this).

                    Originally posted by muncher View Post
                    what is <property name="defaultEntryPoint" ref="defaultAEP"/> ??
                    Did the javadoc not clarify? It none of the RequestMatchers match the request, this is the AuthenticationEntryPoint that is used.

                    HTH,

                    Comment


                    • #11
                      Ok. things are becoming clear.

                      So, to have both form-based and http-based authentication mechanism, I would have to create instance of BasicAuthenticationEntryPoint, LoginUrlAuthenticationEntryPoint and DelegatingAuthenticationEntryPoint and point the entry-point-ref attribute of the <http> block to the DelegatingAuthenticationEntryPoint.

                      But still struggling a bit.

                      so far, I am done with this -

                      Code:
                      ................
                      <beans:bean id="basicAuthenticationFilter"
                      		class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
                      		<beans:property name="authenticationManager" ref="authenticationManager" />
                      		<beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
                      	</beans:bean>
                      
                      	<beans:bean id="authenticationEntryPoint"
                      		class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
                      		<beans:property name="realmName" value="myApp" />
                      	</beans:bean>
                      
                         <beans:bean id="formAuthenticationEntryPoint"
                      		class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
                      		<beans:property name="loginFormUrl" value="${login.page}" />
                         </beans:bean>
                      		
                         <beans:bean id="daep" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
                           <beans:constructor-arg>
                               <beans:map>
                                   <beans:entry key="hasHeader('User-Agent','Mozilla')" value-ref="formAuthenticationEntryPoint" />
                               </beans:map>
                           </beans:constructor-arg>
                           <beans:property name="defaultEntryPoint" ref="authenticationEntryPoint"/>
                       	</beans:bean>
                      .........
                      
                      <http entry-point-ref="daep">
                      ...........
                      ..........
                      </http>
                      1. In the above case, user-agent, identifies that it is a request from the browser and hence proceeds with the login form authentication.
                      else if it is say from curl it does basic authentication.

                      Works fine, if I do request from browser... i.e. works as expected.
                      However, I would want to identify that request is sent from browser as opposed to detecting it from Mozilla only.

                      Also, when I do a curl request, I get back a response of the sort -

                      Code:
                      <h1>HTTP Status 401 - Full authentication is required to access this resource</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Full authentication is required to access this resource</u></p><p><b>description</b> <u>This request requires HTTP authentication (Full authentication is required to access this resource).</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/6.0.26</h3></body></html>
                      Guess basic authentication ain't working. The BasicAuthenticationFilter is never called it seems.
                      Last edited by muncher; Sep 17th, 2010, 04:41 PM.

                      Comment


                      • #12
                        I am looking for ability to use curl to do the restful api calls.

                        Comment


                        • #13
                          Now I am really confused about this one.

                          editing the previous code to include following "in order" works -
                          Code:
                          <http path-type="regex" >
                          .....
                          <http-basic/>
                          <form-login login-page="${login.page}" default-target-url="${login.default-target-url}" />
                          ...
                          ...

                          Comment


                          • #14
                            So you got everything working? The order you place http-basic and form-login should not matter.

                            Comment


                            • #15
                              for the time being yes.

                              One more question so what is the session mapped to ? I mean do we store username, ipaddress ---> jsessionid ?

                              Basically, I am logging in from two different machines using the same username.

                              one from the browser and the other one uses curl. Just wanted to know whether it is acutally using one session that makes the request succesful.

                              Comment

                              Working...
                              X