2014-09-23 47 views

回答

0

springSecurityService本身並不具備這種能力。

但是,沒有什麼會阻止您創建自己的ServletFilter來跟蹤會話標識和安全主體,並公開控制器和頁面以使登錄相關聯的會話無效。

+0

嗯。所以我明白,我可以使用內置的'session'對象來獲取每個用戶的會話ID,但是我使用什麼類或對象來通過ID使任意會話失效? – 2014-09-24 13:35:41

+1

這個以前的問題和答案將幫助您理解我的意思,通過創建您贏得的ServletFilter或SessionListener來跟蹤會話,然後鎖定它們使其無效。 http://stackoverflow.com/questions/1499581/how-can-i-manually-load-a-java-session-using-a-jsessionid – 2014-09-24 15:33:55

0

下面是我如何做到這一點。

編輯:下面的示例使用webxml plugin。您也可以直接編輯web.xml。有關設置超時的信息,請參閱this answer

// src/groovy/com/example/ExpiringSessionEventListener.groovy: 
package com.example 

import grails.util.Holders 
import javax.servlet.http.HttpSessionListener 
import javax.servlet.http.HttpSessionEvent 
import org.springframework.security.core.context.SecurityContext 

public class ExpiringSessionEventListener implements HttpSessionListener { 

    @Override 
    public void sessionCreated(HttpSessionEvent event) { 
     // Do some logging 
    } 

    @Override 
    public void sessionDestroyed(HttpSessionEvent event) { 
     SecurityContext securityContext = event.session.getAttribute("SPRING_SECURITY_CONTEXT") 
     if (securityContext) { 
      UserService userService = Holders.applicationContext.getBean("userService") 
      String userName = securityContext.authentication.principal.username 
      userService.userLoggedOut(userName, event.session.id, Boolean.TRUE) 
     } 
    } 
} 


// grails-app/services/com/example/UserService.groovy: 
package com.example 

import grails.plugin.springsecurity.annotation.Secured 

class UserService { 

    @Secured(["ROLE_USER"]) 
    def userLoggedOut(String userName, String sessionId, Boolean expired) { 
     User user = User.findByUsername(userName) 
     if (expired) { 
      // Do user cleanup stuff after expired session 
     } else { 
      // Do user cleanup stuff after clicking the logout button 
     } 
    } 
} 

編輯:

// grails-app/conf/WebXmlConfig.groovy: 
webxml { 
    sessionConfig.sessionTimeout = 10 // minutes 
    listener.add = true 
    listener.classNames = [ 
     "com.example.ExpiringSessionEventListener" 
    ] 
} 
+0

什麼時候調用sessionDestroyed?我可以打電話記錄任意用戶嗎? – 2014-09-24 13:34:52

+0

我忘了拼圖的關鍵部分。查看關於'''web.xml'''和'''grails-app/conf/WebXmlConfig.groovy''的編輯。當容器超時時,會調用'''sessionDestroyed'''方法,在我的情況下是10分鐘。 – Ken 2014-09-24 13:56:28

+0

我錯過了你的第二個問題。你是什​​麼意思的任意用戶? – Ken 2014-09-24 14:08:15

1

我在我的應用程序,其中,A admin用戶可以註銷的任何強制用戶從當前登錄到系統的所有用戶的列表來完成。

  1. 我目前得到的是所有用戶登錄到系統中,併發送至JSP那裏的所有登錄用戶顯示爲管理員用戶列表。

    @PreAuthorize("hasRole('Currently_Logged-In_Users')") 
     
    \t @RequestMapping(value = "/getLoggedInUsers", method = RequestMethod.POST) 
     
    \t @ResponseBody 
     
    \t public Map<String, List<?>> getLoggedInUsers(Map<String, Object> map ,Model model) { 
     
    \t \t Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
     
    \t  String userName = auth.getName(); 
     
    \t  
     
    \t List<Object> principals = sessionRegistry.getAllPrincipals(); 
     
    
     
    \t List<UserInfo> usersInfoList = new ArrayList<UserInfo>(); 
     
    
     
    \t for (Object principal: principals) { 
     
    \t  if (principal instanceof UserInfo) { 
     
    \t  \t if(!((UserInfo) principal).getUsername().equals(userName)){ 
     
    \t  \t for(SessionInformation sess :sessionRegistry.getAllSessions(principal, false)){ 
     
        \t \t \t if(!sess.isExpired()){ 
     
        \t \t \t \t usersInfoList.add((UserInfo) sess.getPrincipal()); 
     
        \t \t \t } 
     
    \t  \t } 
     
    \t  \t 
     
    \t  \t } 
     
    \t  } 
     
    \t } 
     
    \t 
     
    \t Map<String, List<?>> loggedInUserMap = new HashMap<String, List<?>>(); 
     
    
     
    \t loggedInUserMap.put("loggenInUsers", 
     
    \t \t \t usersInfoList); 
     
    
     
    
     
    \t return loggedInUserMap; 
     
    \t 
     
    \t }

  2. 現在,管理員用戶可以通過點擊對用戶複選框選擇任何用戶或多個用戶。並調用強制退出操作。

    @PreAuthorize("hasRole('Currently_Logged-In_Users')") 
     
    \t @RequestMapping(value = "/logoutSelectedUsers", method = RequestMethod.POST) 
     
    \t @ResponseBody 
     
    \t public Map<String, String> forcedLoggedOut(@RequestParam("userList[]")ArrayList<String> userList ,Model model ,HttpServletRequest request) { 
     
    \t \t 
     
    \t \t Map<String,String> map= new HashMap<String,String>(); 
     
    \t \t try{ 
     
    \t \t \t 
     
    \t \t String successMessage =null; 
     
    \t \t List<String> userCodeList = new ArrayList<String>(); 
     
    \t \t 
     
    \t \t for(String userCode :userList){ 
     
    \t \t \t userCodeList.add(userCode); 
     
    \t \t } 
     
    \t \t \t 
     
    \t \t List<Object> principals = sessionRegistry.getAllPrincipals(); 
     
    \t \t for (Object principal: principals) { 
     
    \t \t  if (principal instanceof UserInfo) { 
     
    \t \t  \t if(userCodeList.contains(((UserInfo) principal).getUsername())){ 
     
    \t \t  \t \t for(SessionInformation sess :sessionRegistry.getAllSessions(principal, false)){ 
     
    \t \t  \t \t \t sess.expireNow(); 
     
    \t \t  \t \t \t successMessage = "msg.loggedOutSuccessfully"; 
     
    \t \t  \t \t \t 
     
    \t \t  \t \t } 
     
    \t \t  \t } 
     
    \t \t  } 
     
    \t \t } 
     
    \t \t 
     
    \t 
     
    \t \t map.put("successmsg", successMessage); 
     
    \t \t } 
     
    \t \t catch(Exception e){ 
     
    \t \t \t map.put("failmsg", "msg.notLoggedOut"); 
     
    \t \t \t logger.error(e.toString(),e); \t 
     
    \t \t \t } 
     
    \t \t return map; 
     
    \t \t 
     
    \t }

+0

不錯,這正是我要找的東西。我必須嘗試一下。 – 2014-09-25 15:25:47

+0

其工作的..因爲我做了同樣的事情...你可以試試它..如果你需要進一步的幫助..你可以問.. :) – 2014-09-26 03:50:34

相關問題