Spring security with multiple login pages

2019-03-12 21:03发布

问题:

I am using Spring security to secure login to the application admin section with a username and password. But now my client need to have another login screen for the application clients section, where they will have their own usernames / passwords to login to the clients section. So far I've already implemented the admin section login successfully with the following spring-security.xml settings:

<security:http auto-config="true" use-expressions="true">
    <security:form-login login-page="/login"
        default-target-url="/admin/dashboard" always-use-default-target="true"
        authentication-failure-url="/login/admin?error_msg=wrong username or password" />
    <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />        
    <security:logout logout-success-url="/login"/>
</security:http>

<security:authentication-manager>
    <security:authentication-provider
        user-service-ref="adminServiceImpl">
    </security:authentication-provider>
</security:authentication-manager>

I've searched the web a lot trying to find how I can add the client section login screen, intercept-url(s), security authentication provider but couldn't find any info, so can someone please help me with any link to any tutorial / example, guide on how to do so?

Thanks

回答1:

According to the Spring Security docs:

From Spring Security 3.1 it is now possible to use multiple http elements to define separate security filter chain configurations for different request patterns. If the pattern attribute is omitted from an http element, it matches all requests.

Each element creates a filter chain within the internal FilterChainProxy and the URL pattern that should be mapped to it. The elements will be added in the order they are declared, so the most specific patterns must again be declared first.

So, essentially you need two <http> elements each with a different pattern attribute.

There's a detailed tutorial here: https://blog.codecentric.de/en/2012/07/spring-security-two-security-realms-in-one-application/



回答2:

I would use only one security:http, but register two UsernamePasswordLoginFilters.

This solution would be appropriate if the two Login-Pages belog to the same security-realm. (So if it does not matter on which Login-Page the user logs in). Of course you can still use roles to restrict the access for different parts of your application for different types of users.

This solution should be quite easy, because you will not need to handle two security:http sections.

The major drawback of this is: that you will have to decide on which of the two login pages a NOT logged in user gets redirected if he try to access an page that requires a login.



回答3:

Example project of Spring MVC App with multiple login forms.

Three types of pages Normal/Member/Admin. If you try to access member page you are brought to Member Login form. If you try to access admin page you go to the Admin Login form.

https://github.com/eric-mckinley/springmultihttploginforms

Done using the ant regex request matcher in the seucrity xml config file.

<beans:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:beans="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/security
                http://www.springframework.org/schema/security/spring-security.xsd">

<global-method-security secured-annotations="enabled" />

<http name="member" pattern="/member/*" request-matcher="ant"   auto-config="true" use-expressions="false">
    <csrf disabled="true"/>

    <intercept-url pattern="/member/home" access="ROLE_MEMBER" />
    <intercept-url pattern="/member/account" access="ROLE_MEMBER" />
    <intercept-url pattern="/member/orders" access="ROLE_MEMBER" />

    <form-login login-page="/member-login" always-use-default-target="false"/>
    <logout logout-url="/logout" logout-success-url="/home"/>
</http>

<http name="admin" request-matcher="regex"   auto-config="true" use-expressions="false">
    <csrf disabled="true"/>

    <intercept-url pattern="/admin/home" access="ROLE_ADMIN" />
    <intercept-url pattern="/admin/users" access="ROLE_ADMIN" />

    <form-login login-page="/admin-login" always-use-default-target="false"/>
    <logout logout-url="/logout" logout-success-url="/home"/>
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="admin" password="password" authorities="ROLE_ADMIN" />
            <user name="member" password="password" authorities="ROLE_MEMBER" />
            <user name="super" password="password" authorities="ROLE_ADMIN,ROLE_MEMBER" />
        </user-service>
    </authentication-provider>
</authentication-manager>



回答4:

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/" access="permitAll" />
    <intercept-url pattern="/login" access="permitAll" />
    <!-- <intercept-url pattern="/welcome/**" access="permitAll" /> <intercept-url 
        pattern="/admin*" access="hasRole('ROLE_ADMIN')" /> -->
    <intercept-url access="hasRole('ROLE_USER')" pattern="/main*" />
    <intercept-url pattern="/main*" access="hasRole('ROLE_USER')" />

    <form-login login-page="/login" default-target-url="/login-success"
        authentication-failure-url="/loginError" />
    <!-- <session-management invalid-session-url="/login" session-fixation-protection="newSession"> 
        <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> 
        </session-management> -->
    <logout logout-success-url="/login" delete-cookies="JSESSIONID" />
    <csrf disabled="true" />
    <headers>
        <frame-options policy="SAMEORIGIN" />
    </headers>
</http>

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/mobile/" access="permitAll" />
    <intercept-url pattern="/mobile/login" access="permitAll" />
    <!-- <intercept-url pattern="/welcome/**" access="permitAll" /> <intercept-url 
        pattern="/admin*" access="hasRole('ROLE_ADMIN')" /> -->
    <intercept-url access="hasRole('ROLE_USER')" pattern="/main*" />
    <intercept-url pattern="/main*" access="hasRole('ROLE_USER')" />
    <form-login login-page="/mobile/login" default-target-url="/mobile/login-success"
        always-use-default-target="true" authentication-failure-url="/mobile/login?error"
        username-parameter="username" password-parameter="password" />
    <logout delete-cookies="JSESSIONID" logout-success-url="/mobile/login" />
    <csrf disabled="true" />
    <headers>
        <frame-options policy="SAMEORIGIN" />
    </headers>

Here I have need two login forms common for all users. I have configured tag element as mentioned above in spring-security.xml.But it is not working. Please suggest me a solution