顧客が要求する機能を実装するのに苦労しています。要するに、彼らは、管理者側を介して、選択した顧客をアプリケーションからログアウトできるようにしたいと考えています。アプリケーションはFlexをフロントエンド技術として使用し、AMF経由でサーバーにアクセスしています。サーバー側は、Spring Security と Spring BlazeDS Integration を使用しています。
基本的には、Spring Security および/または Spring BlazeDS Integration は、すぐに使用できるセッション管理 (および強制終了) のための集中型システムを提供しますか?
概念実証の目的で、次のコードを使用して、すべてのユーザーをログアウトし、すべてのセッションを強制終了しようとしました。
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");
}
}
}
残念ながら、上記のコードは機能しません。私が知る限り、これは次の 2 つの理由によるものです。
A) LoginCommand は「アプリケーション全体」ではなく、現在のセッションに関連付けられているため、現在のセッション (管理者が使用しているセッション) のみをログアウトしようとし、他のセッションを無視します。
B) sessionInformation.expireNow() はセッションを期限切れにしようとしますが、セッションが無効になる前にユーザーがなんとかリクエストを作成した場合、セッションは破棄されません
ドキュメントから、セッションが session.invalidate() によって直接無効化される可能性があることがわかりますが、すべてのセッション オブジェクトにアクセスする方法がないようです。
この種の機能を実装するための最速または最もスマートな方法は何ですか?
よろしく、ジュッカ