我正在使用Spring Security v3.1.4。我想要实现的目标是让管理员能够注销普通用户(使其会话无效)。任何时候一个用户只能登录一次,但如果他忘记注销,则当他试图在另一个位置登录时,将无法登录。所以他会向管理员提出申请,并且管理员将使他之前登录的所有会话无效(希望只有一个)。
在我的web.xml中,我已经定义了以下内容。
我有一个类似于休息的控制器来执行注销操作。
当我从同一台计算机测试代码时,“有点”可以工作。假设我们有一个用户USER_A和一个管理员ADMIN_A。
- USER_A使用Chrome登录APP。 - USER_A使用Firefox登录APP,但被拒绝了,因为一个用户只能同时拥有1个登录会话。 - ADMIN_A进入并调用REST风格的服务(上面的代码)来“踢出”USER_A的所有会话。 - USER_A现在可以使用Firefox登录APP。
然而,USER_A现在在Chrome和Firefox中都已经登录了两次。
- 在Chrome(第一次登录)中刷新USER_A的受Spring Security保护的页面不会强制重定向到登录页面。 - 在Firefox(第二次登录)中刷新USER_A的受保护页面也不会强制重定向。
有什么方法可以完全使USER_A的第一个/之前的登录会话失效/销毁,以便如果他尝试访问受Spring Security保护的页面,Spring Security将知道“嘿,这个家伙的会话无效或过期了,请将他发送到登录页面”?
感谢任何帮助。谢谢。
在我的web.xml中,我已经定义了以下内容。
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
在我的Spring Security XML文件中,我定义了以下内容:
<session-management invalid-session-url="/home">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" session-registry-ref="sessionRegistry"/>
</session-management>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
我有一个类似于休息的控制器来执行注销操作。
@Controller
@RequestMapping("/api/admin")
public class RestAdminController {
static final Set<SimpleGrantedAuthority> AUTHS = new HashSet<>();
static {
AUTHS.add(new SimpleGrantedAuthority("ROLE_USER"));
}
@Autowired
private SessionRegistry sessionRegistry;
@RequestMapping("/user/logout");
public @ResponseBody String logout(@RequestBody Account account) {
User user = new User(account.getUsername(), "", AUTHS);
List<SessionInformation> infos = sessionRegistry.getAllSessions(u, false);
for(SessionInformation info : infos) {
info.expireNow(); //expire the session
sessionRegistry.removeSessionInformation(info.getSessionId()); //remove session
}
return "ok";
}
}
当我从同一台计算机测试代码时,“有点”可以工作。假设我们有一个用户USER_A和一个管理员ADMIN_A。
- USER_A使用Chrome登录APP。 - USER_A使用Firefox登录APP,但被拒绝了,因为一个用户只能同时拥有1个登录会话。 - ADMIN_A进入并调用REST风格的服务(上面的代码)来“踢出”USER_A的所有会话。 - USER_A现在可以使用Firefox登录APP。
然而,USER_A现在在Chrome和Firefox中都已经登录了两次。
- 在Chrome(第一次登录)中刷新USER_A的受Spring Security保护的页面不会强制重定向到登录页面。 - 在Firefox(第二次登录)中刷新USER_A的受保护页面也不会强制重定向。
有什么方法可以完全使USER_A的第一个/之前的登录会话失效/销毁,以便如果他尝试访问受Spring Security保护的页面,Spring Security将知道“嘿,这个家伙的会话无效或过期了,请将他发送到登录页面”?
感谢任何帮助。谢谢。