SpringSecurityService:将其他用户注销?

时间:2014-09-23 21:18:15

标签: grails spring-security

有没有办法让springSecurityService将其他人记录下来?

(例如,如果普通用户离开当天并忘记退出,并且经理想要记录他们的帐户。)

3 个答案:

答案 0 :(得分:1)

我已经在我的应用程序中完成了,管理员用户可以从当前登录到系统的所有用户列表中强行注销任何用户。

  1. 我获取当前登录到系统的所有用户并发送到jsp,其中所有登录用户的列表都显示给管理员用户。

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

  2. 现在,管理员用户可以通过单击对用户的复选框来选择任何用户或多个用户。并调用强制注销操作。

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

答案 1 :(得分:0)

springSecurityService本身没有此功能。

但是,没有什么能阻止您创建自己的ServletFilter来跟踪会话ID和安全主体,并公开控制器和页面以使用登录使相关会话失效。

答案 2 :(得分: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"
    ]
}