-1

我有一个配置了 spring security 和 JSF 和 https 的 Web 应用程序。问题是在我登录应用程序后,如果我在同一个浏览器的新选项卡中再次访问登录页面并尝试使用另一个用户登录,它会验证并再次将第一个用户登录到第二个选项卡(即当我提供第二个用户凭据,这实际上不应该发生)。

1)而不是允许带有登录页面的第二个浏览器选项卡当在浏览器中请求登录页面 URL 并重定向到与 gmail 中相同的受保护页面时,如何检查用户是否已经登录。因此,它将是特定浏览器的单个用户登录。

2)否则我怎样才能允许两个用户在同一个浏览器中使用两个选项卡左右登录?

登录豆

public class LoginBean implements Serializable{

    private String username;    
    private String password;
    private UserDetailsManager userDetailsManager;

    public UserDetailsManager getUserDetailsManager() {
        return userDetailsManager;
    }
    public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
        this.userDetailsManager = userDetailsManager;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    public String login()throws IOException, ServletException{

        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();

        RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
                .getRequestDispatcher("/j_spring_security_check?j_username="+username+"&j_password="+password);

                dispatcher.forward((ServletRequest) context.getRequest(),
                        (ServletResponse) context.getResponse());

                FacesContext.getCurrentInstance().responseComplete();
        return null;

    }
}

Spring-security.xml

    <http auto-config="true">
        <access-denied-handler ref="accessDeniedHandler"/>
        <form-login login-page="/faces/index.xhtml"
            default-target-url="/faces/xxxx/protectedPage.xhtml"
            always-use-default-target="true" authentication-failure-url="/faces/index.xhtml?error=true" />

    <intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/faces/xxxx/protectedPage.xhtml" access="ROLE_USER" requires-channel="https"/>

    <port-mappings>
        <port-mapping http="8080" https="8443"/>
    </port-mappings>

    <logout invalidate-session="true" logout-success-url="/faces/index.xhtml" logout-url="/j_spring_security_logout" />

    <session-management session-fixation-protection="newSession" invalid-session-url="/faces/index.xhtml" session-authentication-error-url="/faces/index.xhtml?errorMessage=The session is expired due to another user logging in with your user name and password.">
        <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/sessionExpired.xhtml?errorMessage=The session is expired! Please reLogin" />
    </session-management> 

    </http>

    <jee:jndi-lookup id="dataSource" jndi-name="java:MyDS" />

    <authentication-manager>
        <authentication-provider>
            <password-encoder hash="sha-256" />
            <jdbc-user-service data-source-ref="dataSource" />
        </authentication-provider>
    </authentication-manager>

Faces-config.xml

<managed-bean>
  <managed-bean-name>loginBean</managed-bean-name>
  <managed-bean-class>com.xxxx.jsf.security.LoginBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
   <property-name>userDetailsManager</property-name>
   <value>#{userDetailsManager}</value>
  </managed-property>
 </managed-bean>
<application>
  <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
 </application>
<lifecycle>
    <phase-listener>com.ustocktrade.jsf.listener.LoginErrorPhaseListener</phase-listener>
</lifecycle>

web.xml

<context-param>
  <param-name>com.sun.faces.numberOfLogicalViews</param-name>
  <param-value>2</param-value>
 </context-param>
 <context-param>
  <param-name>com.sun.faces.numberOfViewsInSession</param-name>
  <param-value>2</param-value>
 </context-param>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/user-config.xml 
  /WEB-INF/spring-security.xml</param-value>
 </context-param>
 <context-param>
  <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
  <param-value>.xhtml</param-value>
 </context-param>
 <context-param>
  <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>server</param-value>
 </context-param>
 <context-param>
  <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
  <param-value>resources.application</param-value>
 </context-param>
 <context-param>
  <param-name>log4jConfigLocation</param-name>
  <param-value>/WEB-INF/resources/log4j.properties</param-value>
 </context-param>
 <context-param>
  <param-name>log4jExposeWebAppRoot</param-name>
  <param-value>false</param-value>
 </context-param>
 <context-param>
  <param-name>log4jRefreshInterval</param-name>
  <param-value>1000</param-value>
 </context-param>
<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>ERROR</dispatcher>
 </filter-mapping>
<listener>
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 </listener>
 <listener>
  <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
 </listener>
 <listener>
  <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
 </listener>
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <listener>
  <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
 </listener>
 <servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
<session-config>
  <session-timeout>5</session-timeout>
 </session-config>
 <welcome-file-list>
  <welcome-file>faces/index.xhtml</welcome-file>
 </welcome-file-list>
 <error-page>
  <exception-type>javax.faces.application.ViewExpiredException</exception-type>
  <location>/sessionExpired.xhtml</location>
 </error-page>
 <error-page>
  <error-code>404</error-code>
  <location>/errors/404.xhtml</location>
 </error-page>
 <error-page>
  <error-code>403</error-code>
  <location>/errors/403.xhtml</location>
 </error-page>
 <error-page>
  <error-code>500</error-code>
  <location>/errors/500.xhtml</location>
 </error-page>
4

1 回答 1

0

在您的登录表单中,使用您的默认目标 url 作为您的主页链接。这样,一旦通过身份验证和授权,它将重定向到主页。

<form-login login-page="/rest/admin/adminLogin" 
                        default-target-url="/rest/admin/adminHome"
                        login-processing-url="/rest/admin/login_process"
                        authentication-failure-url="/rest/admin/adminLogin?error" 
                        username-parameter="emailId"
                        password-parameter="password" 
                        always-use-default-target="true" /> 

一旦你观察到上面的代码,我在成功登录后使用 adminHome 作为我的默认目标 url。如果它没有经过身份验证,则意味着它将重定向到再次登录页面。但是在同一个浏览器中使用两个帐户登录是不可能的,只有 spring security 它只可以使用 spring 会话多登录功能,会话在某些地方持续存在(例如将会话令牌保存在 cookie、header 中或使用 spring-data(redis,nosql...)/RDBMS

于 2017-02-03T07:16:37.977 回答