Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring security - how to mention both form based and basic authentication

Is it possible to mention both form-based and basic authentication in Spring security using namespace configuration without overriding other ? So that the appliciation could serve both browser based request and remoting client.

like image 883
Maniganda Prakash Avatar asked Aug 19 '09 00:08

Maniganda Prakash


People also ask

How you can say that form-based authentication is highly Customised?

With form-based authentication, you can customize the login screen and error pages that are presented to the web client for authentication of their user name and password.

What does formLogin () do in Spring Security?

Form-based login is one form of Username/password authentication that Spring Security provides support for. This is provided through an Html form. Whenever a user requests a protected resource, Spring Security checks for the authentication of the request.

Does Spring Security use default login form?

In this configuration Spring Security will render a default log in page. Most production applications will require a custom log in form. The configuration below demonstrates how to provide a custom log in form. public SecurityFilterChain filterChain(HttpSecurity http) { http .

What is the difference between basic and form-based authentication?

Unlike Form-Based Authentication, Basic Authentication DO NOT use cookies, hence there is no concept of a session or logging out a user, which means each request has to carry that header in order to be authenticated. Form-Based Authentication in the other hand is not formalized by any RFC.


2 Answers

The response by @grimesjm is right. However, if you are using Spring 3.x you have to adapt the class names to:

<bean id="basicProcessingFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
    <property name="authenticationManager">
        <ref bean="authenticationManager" />
    </property> 
    <property name="authenticationEntryPoint">
        <ref bean="authenticationEntryPoint" />
    </property>
</bean>

<bean id="authenticationEntryPoint"
    class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
    <property name="realmName" value="Your realm here" />
</bean>

And

<sec:http auto-config="true">
    ... your intercept-url here

    <sec:custom-filter before="SECURITY_CONTEXT_FILTER" ref="basicProcessingFilter" />

    <sec:form-login ... />
    ....
</sec:http>

I do not know whether placing the filter before SECURITY_CONTEXT_FILTER is the best option or not.

like image 93
Guido Avatar answered Oct 25 '22 21:10

Guido


The end result you want is possible, I have ran into that exact same problem and here is my solution.

Anytime when defining form-login in the namespace it will override automatically any other authentication filters you apply via namespace. This is done through the ordering of the filter chain look at FilterChainOrder.java in the spring security to see how the order is actually applied to each filter.

To get around this remove the http-basic tag from the namespace then manually define the bean to handle basic authentication and place its order before the AuthenticationProcessingFilter because this is the spring security filter that will handle the form-login.

The BasicProcessingFilter spring provides to handle Basic authentication is a passive filter, meaning that if the credentials are missing it will continue down the filter chain until it finds the appropriate filter to handle the request.

Now by manually defining the BasicProcessingFilter bean we can set the order that it will appear in the filter chain. Below is an example of the additional xml declarations you will need to supply in the security xml (Spring Security < 3.x)

<bean id="basicProcessingFilter" class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
    <property name="authenticationManager"><ref bean="authenticationManager"/></property>
     <security:custom-filter before="AUTHENTICATION_PROCESSING_FILTER"/>
    <property name="authenticationEntryPoint"><ref bean="authenticationEntryPoint"/></property>
</bean>

<bean id="authenticationEntryPoint"
    class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
              <property name="realmName" value="My Realm Here"/>
</bean>

Also note if your authenticationManager reference isn't found you can add an alias to your namespace like the one below.

<security:authentication-manager alias="authenticationManager"/>

The end result is the basic filter will be applied as a passive filter and if its required credentials are missing it will continue down the filter chain and the form-login filter will then handle it.

The problem with this approach is that if credentials are correctly entered, the response back is the login page from the form-login filter.

However, It appears that this problem will be fixed by spring in version 3.1 of spring security and this work around will no longer be needed.

like image 42
grimesjm Avatar answered Oct 25 '22 19:10

grimesjm