2015-09-08 31 views
2

如果管理員想阻止其他用戶,我希望能夠強制其他用戶註銷。SessionInformation過期不會導致用戶從系統註銷

我已閱讀以下的答案

How do you log out all logged in users in spring-security?

我已經寫了下面的代碼:

@Autowired 
private SessionRegistry sessionRegistry; 
... 
private void logout(String name) { 
    System.out.println(name); 
    for (Object principal : sessionRegistry.getAllPrincipals()) { 
     User user = (User) principal; 
     if (user.getUsername().equals(name)) { 
      sessionRegistry.getAllSessions(principal, false).stream() 
        .forEach(i -> i.expireNow()); 
     } 
    } 
} 

我打開2級的瀏覽器(1管理員和2用戶)

我同時登錄。

管理員點擊阻止用戶

在調試,我到

if (user.getUsername().equals(name)) { 

而看到以下狀態: enter image description here

但是這個代碼後執行用戶仍然登錄系統,並且可以滾動現場。

如果重複此操作,sessionRegistry.getAllSessions(principal, false)將返回空列表。

Spring的安全配置:

<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-4.0.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security-3.2.xsd 
     "> 

    <http auto-config="true" pattern="/admin/**" authentication-manager-ref="adminAuthenticationManager"> 
     <access-denied-handler error-page="/403" /> 
     <form-login login-page="/loginAdmin" login-processing-url="/admin/j_spring_security_check_admin" 
        default-target-url="/admin" 
        authentication-failure-url="/loginAdminFailed" 
        authentication-success-handler-ref="authAdminSuccessHandler"/> 

     <intercept-url pattern="/admin/j_spring_security_check_admin" access="ROLE_ANONYMOUS"/> 
     <intercept-url pattern="/admin/accounts/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/users/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/terminals/**" access="ROLE_SUPERADMIN, ROLE_TERMINAL_MODERATOR, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/money/**" access="ROLE_FINANSIER, ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/moderation/**" access="ROLE_SUPERADMIN,ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/moderation/pictures" 
         access="ROLE_SUPERADMIN,ROLE_MODERATOR, ROLE_IMAGE_MODERATOR"/> 
     <intercept-url pattern="/admin/statistic/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/rules/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/terminals/addImageToTerminal" 
         access="ROLE_SUPERADMIN, ROLE_TERMINAL_MODERATOR, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/terminals/deleteTerminalImage" 
         access="ROLE_SUPERADMIN, ROLE_TERMINAL_MODERATOR, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/systemGroupsModeration" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/adminUsers" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/contentModeration/**" access="ROLE_SUPERADMIN, ROLE_MODERATOR, ROLE_IMAGE_MODERATOR"/> 
     <intercept-url pattern="/admin/campaignModeration/**" access="ROLE_SUPERADMIN, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/monitoring" access="ROLE_SUPERADMIN"/> 

     <logout logout-url="/logout" logout-success-url="/loginAdmin"/> 
     <port-mappings> 
      <port-mapping http="${http.port}" https="${https.port}"/> 
     </port-mappings> 
     <session-management session-authentication-strategy-ref="sas" invalid-session-url="/invalid-session" /> 
    </http>  

    <beans:bean id="userSecurityService" class="com.terminal.service.impl.UserSecurityService"/> 
    <beans:bean id="authSuccessHandler" class="com.terminal.filter.RoleAuthSuccessHandler"/> 

    <beans:bean id="authAdminSuccessHandler" class="com.terminal.filter.admin.RoleAuthAdminHandler"/> 
    <beans:bean id="adminSecurityService" class="com.terminal.service.admin.impl.TerminalAdminSecurityServiceImpl"/> 

    <beans:bean id="webexpressionHandler" 
       class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/> 

    <authentication-manager id="adminAuthenticationManager"> 
     <authentication-provider user-service-ref="adminSecurityService"> 
      <password-encoder ref="encoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <authentication-manager id="userAuthenticationManager"> 
     <authentication-provider user-service-ref="userSecurityService"> 
      <password-encoder ref="encoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <authentication-manager id="internalUserAuthenticationManager"> 
     <authentication-provider user-service-ref="userSecurityService"> 
      <password-encoder ref="noopEncoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
     <beans:constructor-arg index="0" value="10"/> 
    </beans:bean> 
    <beans:bean id="noopEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/> 
    <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/> 
    <beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy"> 
     <beans:constructor-arg ref="sessionRegistry" /> 
     <beans:property name="maximumSessions" value="1" /> 
    </beans:bean> 
</beans:beans> 
+0

可以滾動的網站?如果你刷新頁面怎麼辦? –

+0

在'SessionRegistry'中使用的會話不是'HttpSession',它們是不同的東西。 –

+0

@Predrag Maric刷新頁面後用戶仍然登錄 – gstackoverflow

回答

1

這工作:

春季安全配置:

<beans:beans 
     xmlns="http://www.springframework.org/schema/security" 
     xmlns:beans="http://www.springframework.org/schema/beans" 
     xmlns:sec="http://www.springframework.org/schema/security" 
     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-4.0.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security.xsd"> 

    <http auto-config="true" pattern="/admin/**" authentication-manager-ref="adminAuthenticationManager"> 
     <access-denied-handler error-page="/403" /> 
     <custom-filter ref="concurrencyFilter" after="SECURITY_CONTEXT_FILTER"/> 
     <form-login login-page="/loginAdmin" login-processing-url="/admin/j_spring_security_check_admin" 
        default-target-url="/admin" 
        authentication-failure-url="/loginAdminFailed" 
        authentication-success-handler-ref="authAdminSuccessHandler"/> 

     <intercept-url pattern="/admin/j_spring_security_check_admin" access="ROLE_ANONYMOUS"/> 
     <intercept-url pattern="/admin/accounts/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/users/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/terminals/**" access="ROLE_SUPERADMIN, ROLE_TERMINAL_MODERATOR, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/money/**" access="ROLE_FINANSIER, ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/moderation/**" access="ROLE_SUPERADMIN,ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/moderation/pictures" 
         access="ROLE_SUPERADMIN,ROLE_MODERATOR, ROLE_IMAGE_MODERATOR"/> 
     <intercept-url pattern="/admin/statistic/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/rules/**" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/terminals/addImageToTerminal" 
         access="ROLE_SUPERADMIN, ROLE_TERMINAL_MODERATOR, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/terminals/deleteTerminalImage" 
         access="ROLE_SUPERADMIN, ROLE_TERMINAL_MODERATOR, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/systemGroupsModeration" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/adminUsers" access="ROLE_SUPERADMIN"/> 
     <intercept-url pattern="/admin/contentModeration/**" access="ROLE_SUPERADMIN, ROLE_MODERATOR, ROLE_IMAGE_MODERATOR"/> 
     <intercept-url pattern="/admin/campaignModeration/**" access="ROLE_SUPERADMIN, ROLE_MODERATOR"/> 
     <intercept-url pattern="/admin/monitoring" access="ROLE_SUPERADMIN"/> 

     <logout logout-url="/logout" logout-success-url="/loginAdmin"/> 
     <port-mappings> 
      <port-mapping http="${http.port}" https="${https.port}"/> 
     </port-mappings> 
     <session-management session-authentication-strategy-ref="sas" invalid-session-url="/" /> 
    </http> 


    <beans:bean id="userSecurityService" class="com.terminal.service.impl.UserSecurityService"/> 
    <beans:bean id="authSuccessHandler" class="com.terminal.filter.RoleAuthSuccessHandler"/> 

    <beans:bean id="authAdminSuccessHandler" class="com.terminal.filter.admin.RoleAuthAdminHandler"/> 
    <beans:bean id="adminSecurityService" class="com.terminal.service.admin.impl.TerminalAdminSecurityServiceImpl"/> 

    <beans:bean id="webexpressionHandler" 
       class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/> 

    <authentication-manager id="adminAuthenticationManager"> 
     <authentication-provider user-service-ref="adminSecurityService"> 
      <password-encoder ref="encoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <authentication-manager id="userAuthenticationManager"> 
     <authentication-provider user-service-ref="userSecurityService"> 
      <password-encoder ref="encoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <authentication-manager id="internalUserAuthenticationManager"> 
     <authentication-provider user-service-ref="userSecurityService"> 
      <password-encoder ref="noopEncoder"/> 
     </authentication-provider> 
    </authentication-manager> 

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> 
     <beans:constructor-arg index="0" value="10"/> 
    </beans:bean> 
    <beans:bean id="noopEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/> 

    <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/> 

    <beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy"> 
     <beans:constructor-arg> 
      <beans:list> 
       <beans:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy"> 
        <beans:constructor-arg ref="sessionRegistry"/> 
        <beans:property name="maximumSessions" value="1" /> 
        <beans:property name="exceptionIfMaximumExceeded" value="true" /> 
       </beans:bean> 
       <beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"> 
       </beans:bean> 
       <beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy"> 
        <beans:constructor-arg ref="sessionRegistry"/> 
       </beans:bean> 
      </beans:list> 
     </beans:constructor-arg> 
    </beans:bean> 

    <beans:bean id="concurrencyFilter" 
       class="org.springframework.security.web.session.ConcurrentSessionFilter"> 
     <beans:property name="sessionRegistry" ref="sessionRegistry" /> 
     <beans:property name="expiredUrl" value="/" /> 
    </beans:bean> 

</beans:beans> 

裏面logout方法我們設置信息會被裏面的SessionRegistry過期,concurrencyFilter閱讀本並過期http會話。

我也加入

<listener> 
     <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> 

</listener> 

到web.xml