Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling both form and HTTP basic authentication with different sources

I already have form login and Basic auth working side by side with the help of a DelegatingAuthenticationEntryPoint.

What I'm trying to do is have users coming thru the login form to be authenticated against criteria "A", and have users coming thru the Basic auth requests to be authenticated against criteria "B".

Some of the application's resources are exposed thru a RESTful service (accessible via Basic auth). Instead of having users enter their own credentials to make a REST service call, they can enter generated key/value pairs for use exclusively with the REST service that can later be revoked by the user or by the app administrator.

I would prefer to share as much of my security-specific beans as possible between the two methods of authentication. I know I will need separate UserDetailsServices as the form login queries my users table, and Basic auth will query my service_credentials table.

What is the correct way to achieve this kind of configuration in Spring Security?

like image 334
The Awnry Bear Avatar asked Feb 15 '12 22:02

The Awnry Bear


People also ask

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.

How can I pass the basic HTTP authentication?

We can do HTTP basic authentication URL with @ in password. We have to pass the credentials appended with the URL. The username and password must be added with the format − https://username:password@URL.

What is an important thing to keep in mind if using the Basic Authentication type in Apache?

It is important to be aware, however, that Basic authentication sends the password from the client to the server unencrypted. This method should therefore not be used for highly sensitive data, unless accompanied by mod_ssl . Apache supports one other authentication method: AuthType Digest .

How does Basic Authentication that can be set at the Web server level work?

Basic authentication sends user names and passwords over the Internet as text that is Base64 encoded, and the target server is not authenticated. This form of authentication can expose user names and passwords. If someone can intercept the transmission, the user name and password information can easily be decoded.


2 Answers

Depending on your app and whether you're using Spring Security 3.1, you might be best to split the configuration into multiple filter chains, each with a separate authentication manager defined:

<http pattern="/rest_api/**" create-session="stateless"
    authentication-manager-ref="serviceCredsAuthMgr">
    <http-basic />
</http>

<http authentication-manager-ref="mainAuthMgr">
    <form-login />
</http>

<authentication-manager id="serviceCredsAuthMgr">
    <authentication-provider user-service-ref="serviceCredsUserDetailsSvc" />
</authentication-manager>

<authentication-manager id="mainAuthMgr">
    <!-- whatever -->
</authentication-manager>

Instead of the pattern attribute you can also use the request-matcher-ref attribute to specify a RequestMatcher instance which will be used to map incoming requests to a particular filter chain. This has a very simple interface, but can allow you to match based on something other than the URL path, such as the Accept header.

like image 82
Shaun the Sheep Avatar answered Oct 24 '22 03:10

Shaun the Sheep


With SpringSecurity (3.2.3.RELEASE) work fine form as well as basic auth:

<http pattern="/resources/**" security="none"/>
<http pattern="/webjars/**" security="none"/>

<http pattern="/rest/**" create-session="stateless" use-expressions="true">
    <intercept-url pattern="/**" access="isFullyAuthenticated()"/>
    <http-basic />
</http>

<http auto-config="true" use-expressions="true">
    <http-basic/>
    <intercept-url pattern="/login" access="permitAll"/>
    <intercept-url pattern="/loginfailed" access="permitAll"/>
    <intercept-url pattern="/logout" access="permitAll"/>

    <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')"/>
    <intercept-url pattern="/**" access="isAuthenticated()"/>
    <form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed"/>
    <logout logout-success-url="/logout"/>
    <remember-me user-service-ref="userService"/>
</http>

<authentication-manager>
    <authentication-provider user-service-ref="userService">
<!--
        <jdbc-user-service data-source-ref="dataSource"
                           users-by-username-query="SELECT email, password, enabled FROM users WHERE email = ?"
                           authorities-by-username-query="
                                       SELECT u.email, r.name FROM users u, roles r WHERE u.id = r.user_id and u.email = ?"/>
-->
<!--
        <user-service>
            <user name="[email protected]" password="password" authorities="ROLE_USER"/>
            <user name="[email protected]" password="admin" authorities="ROLE_ADMIN"/>
        </user-service>
-->
    </authentication-provider>
</authentication-manager>
like image 39
Grigory Kislin Avatar answered Oct 24 '22 05:10

Grigory Kislin