Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SpringSecurity4中配置一个登录页面和多个登录页面,这些登录页面使用不同的url模式进行拦截_Spring_Jsp_Spring Mvc_Spring Security - Fatal编程技术网

如何在SpringSecurity4中配置一个登录页面和多个登录页面,这些登录页面使用不同的url模式进行拦截

如何在SpringSecurity4中配置一个登录页面和多个登录页面,这些登录页面使用不同的url模式进行拦截,spring,jsp,spring-mvc,spring-security,Spring,Jsp,Spring Mvc,Spring Security,我的要求是,我有两个不同的登录页一个用户和一个管理员。此登录页必须基于我在SpringSecurityXML文件中配置的拦截url模式显示。两个登录页都有一个登录的超链接,当用户单击adminLayout.jsp的登录超链接时,它将加载相同的登录页面;当用户单击userLayout.jsp的登录超链接时,它将通过与控制器交互两种不同的url模式来加载相同的登录页面。url模式将为/admin和/user 我被困在这里。 如何在SpringSecurity中配置两个不同的登录页(adminLayo

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

我被困在这里。 如何在SpringSecurity中配置两个不同的登录页(adminLayout和userLayout)。这两个登录页具有相同的登录表单,我想在spring security表单登录中配置url模式和两种布局。登录前只需显示登录页,然后当用户从两个不同页面单击登录超链接时,必须使用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> 

创建自定义的
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);
         }
    }

}
并使用
表单登录
标签进行配置,如下所示

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

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

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

创建一个自定义的
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);
         }
    }

}
并使用
表单登录
标签进行配置,如下所示

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

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

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

我认为您应该尝试创建一个支持多登录页面的实现

可能是这样的:

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);
    }

}
import java.util.Map;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入org.springframework.security.core.AuthenticationException;
导入org.springframework.security.web.AuthenticationEntryPoint;
导入org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
导入org.springframework.security.web.util.matcher.RegexRequestMatcher;
导入org.springframework.security.web.util.matcher.RequestMatcher;
公共类MultipleLandingPageEntryPoint扩展了LoginUrauThenticationEntryPoint
实现AuthenticationEntryPoint{
私人地图登陆页面;
公共MultipleLandingPageEntryPoint(字符串defaultLoginFormUrl,地图登录页){
super(defaultLoginFormUrl);
this.landingPages=landingPages;
}
公共MultipleLandingPageEntryPoint(字符串defaultLoginFormUrl){
super(defaultLoginFormUrl);
}
公共地图getLandingPages(){
返回登陆页面;
}
公共无效设置登录页(地图登录页){
this.landingPages=landingPages;
}
@凌驾
此请求的受保护字符串determinuteUrlToUse(HttpServletRequest请求、HttpServletResponse响应、,
AuthenticationException(异常){
for(字符串键:this.landingPages.keySet()){
RequestMatcher rm=新的RegexRequestMatcher(key,null);
如果(rm.匹配(请求)){
返回此.landingPages.get(键);
}
}
//如果在地图中找不到,则通过超类返回默认登录页
返回此请求的super.determineurltouse(请求、响应、异常);
}
}
然后,在安全配置中,必须对其进行配置:

    <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 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">

如果实现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);
    }

}
import java.util.Map;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入org.springframework.security.core.AuthenticationException;
导入org.springframework.security.web.AuthenticationEntryPoint;
导入org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
导入org.springframework.security.web.util.matcher.RegexRequestMatcher;
导入org.springframework.security.web.util.matcher.RequestMatcher;
公共类MultipleLandingPageEntryPoint扩展了LoginUrauThenticationEntryPoint
实现AuthenticationEntryPoint{
私人地图登陆页面;
公共MultipleLandingPageEntryPoint(字符串defaultLoginFormUrl,地图登录页){
super(defaultLoginFormUrl);
this.landingPages=landingPages;
}
公共MultipleLandingPageEntryPoint(字符串defaultLoginFormUrl){
super(defaultLoginFormUrl);
}
公共地图getLandingPages(){
返回登陆页面;
}
公共无效设置登录页(地图登录页){
this.landingPages=landingPages;
}
@凌驾
此请求的受保护字符串determinuteUrlToUse(HttpServletRequest请求、HttpServletResponse响应、,
AuthenticationException(异常){
for(字符串键:this.landingPages.keySet()){
RequestMatcher rm=新的RegexRequestMatcher(key,null);
如果(rm.匹配(请求)){
返回此.landingPages.get(键);
}
}
//如果在地图中找不到,则通过超类返回默认登录页
返回此请求的super.determineurltouse(请求、响应、异常);
}
}
然后,在安全配置中,必须对其进行配置:

    <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>