我很難實現我們客戶請求的功能。簡而言之,他們希望能夠通過管理員端從應用程序中註銷他們選擇的任何客戶。該應用程序使用Flex作爲前端技術並通過AMF訪問服務器。服務器端使用Spring Security和Spring BlazeDS集成。針對Spring Security和/或Spring BlazeDS集成的會話管理(和查殺)集中式系統
基本上問題是:Spring Security和/或Spring BlazeDS集成是否提供了任何集中式會話管理(和查殺)開箱即用的系統?
爲了證明的概念目的,我曾試圖註銷所有用戶,並殺死下面的代碼的所有會話:
package xxx.xxx.xxx;
import java.util.List;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.User;
import flex.messaging.MessageBroker;
import flex.messaging.security.LoginCommand;
public class SessionServiceImpl {
private static final Log log = LogFactory.getLog(SessionServiceImpl.class);
private SessionRegistry sessionRegistry;
private MessageBroker messageBroker;
public SessionRegistry getSessionRegistry() {
return sessionRegistry;
}
@Autowired
public void setSessionRegistry(SessionRegistry sessionRegistry) {
log.debug("sessionregistry set");
this.sessionRegistry = sessionRegistry;
}
public MessageBroker getMessageBroker() {
return messageBroker;
}
@Autowired
public void setMessageBroker(MessageBroker messageBroker) {
log.debug("messagebroker set");
this.messageBroker = messageBroker;
}
public void logoutUser(String userName) {
log.debug("Logging out user by username: "+userName);
List<Object> principals = null;
if(sessionRegistry != null){
principals = sessionRegistry.getAllPrincipals();
}else{
log.debug("sessionRegistry null");
}
if(principals != null){
for (Object object : principals) {
User user = (User)object;
// get single users all sessions
List<SessionInformation> sessions = sessionRegistry.getAllSessions(user, false);
log.debug("Sessions list size: "+sessions.size());
if(messageBroker != null){
LoginCommand command = messageBroker.getLoginManager().getLoginCommand();
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user, user.getPassword());
command.logout(usernamePasswordAuthenticationToken);
for (SessionInformation sessionInformation : sessions) {
log.debug(ReflectionToStringBuilder.toString(sessionInformation));
sessionInformation.expireNow();
sessionRegistry.removeSessionInformation(sessionInformation.getSessionId());
}
}else{
log.debug("messageBroker null");
}
if(object != null){
log.debug(ReflectionToStringBuilder.toString(object));
}else{
log.debug("object null");
}
}
}else{
log.debug("principals null");
}
}
}
不幸的是,上面的代碼不起作用。至於我可以告訴大家,這是因爲兩件事情:
A)LoginCommand不是「應用廣泛」,但綁在當前會話,因此它會嘗試登出目前唯一的會話(管理員使用會話)和是無視其他會話
B)sessionInformation.expireNow()嘗試到期的會話,但如果用戶管理,使請求會話被失效前,該會話不被破壞
從文檔我可以看到,會話可以通過session.invalidate()直接失效,但似乎我無法訪問所有會話對象。
什麼是最快或最聰明的方式來實現這種功能?
最好的問候, 尤卡
除非我誤會,這不起作用,因爲'SessionAuthenticationStrategy'在登錄時只使用,不上後續請求。 –