如何使用多个登录页面配置一个登录页面,该页面在spring security 4

时间:2016-11-15 05:57:15

标签: spring jsp spring-mvc spring-security

我的要求是,我有两个不同的目标网页,一个用于用户,一个用于管理员。此登录页面必须基于我在spring security xml文件中配置的拦截URL模式显示。登陆页面都有一个登录的超链接,当用户点击adminLayout.jsp的登录超链接时,它将加载相同的登录页面,当用户点击userLayout.jsp的登录超链接时,它将加载相同的登录页面通过与控制器交互两个不同的url模式。网址模式将是/ admin和/ user。

我住在这里。 如何在spring安全性中配置两个不同的登录页面(adminLayout)和userLayout。这两个登录页面具有相同的登录表单,我想在弹簧安全表单中配置 - 登录网址模式和两个布局。在登录之前,只有登录页面必须出现,然后当用户点击登录时来自两个不同页面的超链接,它必须使spring security的用户提供登录表单功能。请帮我解决这个问题。

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" requires-channel="http" />
       <intercept-url pattern="/user**" access="hasRole('ROLE_USER')" requires-channel="http" />   
    <csrf disabled="true"/>
      <access-denied-handler ref="accessDeniedHandler"/>
    <!-- Here i want to configure the landing pages based on the intercept url pattern if the pattern is /admin i want to dispaly the adminLayout.
    If the intercept url pattern is /user i want to display the userLayout. Both this Layout pages is having common login page which user will click from this layout pages.
    if want to make use of spring secuiryt for form login..
     -->    
 <form-login login-processing-url="/j_spring_security_check"
        login-page="/sslogin"  authentication-success-handler-ref="authenticationHandler" 
        authentication-failure-url="/fail2login?error=true"/>
    <logout  logout-success-url="/logout" invalidate-session="true" logout-url="/j_spring_security_logout" delete-cookies="JSESSIONID" />  


<session-management>
<concurrency-control error-if-maximum-exceeded="true" max-sessions="1" expired-url="/fail2login"  />
</session-management>
</http>
<beans:bean id="accessDeniedHandler" class="com.fss.portal.handlers.PortalAccessDeniedHandler">
 <beans:property name="accessDeniedURL" value="403"></beans:property>
</beans:bean>
<beans:bean id="authenticationHandler" class="com.fss.portal.handlers.AuthenticationHandler">
</beans:bean> 
<beans:bean id="customAuthenticationProvider" class="com.fss.portal.utility.CustomAuthenticationProvider">
 <beans:property name="passwordEncoder" ref="bcryptEncoder"></beans:property>
</beans:bean> 
 <beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

 <authentication-manager>
    <authentication-provider  ref="customAuthenticationProvider">
    </authentication-provider>
</authentication-manager> 

2 个答案:

答案 0 :(得分:1)

创建自定义AuthenticationSuccessHandler,如下所示

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    public void onAuthenticationSuccess(javax.servlet.http.HttpServletRequest request,
                           javax.servlet.http.HttpServletResponse response,
                           Authentication authentication)
                             throws IOException,
                                    javax.servlet.ServletException {
         if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN")) {
              request.getRequestDispatcher("/admin").forward(request, response);
         } else if (authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_USER")) {
              request.getRequestDispatcher("/user").forward(request, response);
         }
    }

}

并使用form-login标记对其进行配置,如下所示

<bean id="customAuthenticationSuccessHandler" class="CustomAuthenticationSuccessHandler" />

<form-login authentication-success-handler-ref="customAuthenticationSuccessHandler" ...>

<强>更新

创建一个控制器映射/landing指向<form-login login-page="/landing" .../>。此着陆应包含管理员和用户登录页面的链接。哪个可以有登录链接或表格。

您可以从这些目标网页中删除保护。

<http pattern="/landing**" security="none"/>
<http pattern="/landing/admin**" security="none"/>
<http pattern="/landing/user**" security="none"/>

您可以编写自定义AuthenticationFailureHandler以重定向到正确的登录页面。

答案 1 :(得分:1)

我认为您应该尝试创建一个具有多个着陆页支持的AuthenticationEntryPoint实现。

可能是这样的:

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

public class MultipleLandingPageEntryPoint extends LoginUrlAuthenticationEntryPoint
        implements AuthenticationEntryPoint {

    private Map<String, String> landingPages;

    public MultipleLandingPageEntryPoint(String defaultLoginFormUrl, Map<String, String> landingPages) {
         super(defaultLoginFormUrl);
         this.landingPages = landingPages;
    }

    public MultipleLandingPageEntryPoint(String defaultLoginFormUrl) {
        super(defaultLoginFormUrl);
    }

    public Map<String, String> getLandingPages() {
        return landingPages;
    }

    public void setLandingPages(Map<String, String> landingPages) {
        this.landingPages = landingPages;
    }

    @Override
    protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) {
        for(String key : this.landingPages.keySet()){
            RequestMatcher rm = new RegexRequestMatcher(key, null);
            if(rm.matches(request)){
                return this.landingPages.get(key);
            }
        }
        // If not found in the map, return the default landing page through superclass
        return super.determineUrlToUseForThisRequest(request, response, exception);
    }

}

然后,在您的安全配置中,您必须配置它:

    <beans:bean id="authenticationMultiEntryPoint" class="com.xxx.yyy.MultipleLandingPageEntryPoint">
        <beans:constructor-arg value="/user/landing.htm" />
        <beans:property name="landingPages">
            <beans:map>
                <beans:entry key="/user**" value="/user/landing.htm" />
                <beans:entry key="/admin**" value="/admin/landing.htm" />
            </beans:map>
        </beans:property>
    </beans:bean>

并在<security:http>元素中使用它:

    <security:http pattern="/admin/landing.htm" security="none" />
    <security:http pattern="/user/landing.htm" security="none" />
    <security:http auto-config="true" use-expressions="true" 
              entry-point-ref="authenticationMultiEntryPoint">

如果你实现了扩展LoginUrlAuthenticationEntryPoint的AuthenticationEntryPoint(我认为这是一个好主意),请检查其他参数。

编辑:我刚刚更新了类实现,没有包含最新版本

相关问题