복붙노트

[SPRING] 스프링 보안을 사용하여 프로그래밍 방식으로 사용자를 로그 아웃하는 방법

SPRING

스프링 보안을 사용하여 프로그래밍 방식으로 사용자를 로그 아웃하는 방법

나는 스프링 보안 v3.1.4를 사용하고있다. 내가 원하는 것은 관리자가 일반 사용자를 로그 아웃 (세션을 무효화) 할 수있게하는 것입니다. 사용자는 주어진 시간에 한 번만 로그인 할 수 있지만 로그 아웃하는 것을 잊어 버린 경우 다른 위치에서 로그인하려고하면 로그인 할 수 없으므로 로그인 할 수 없습니다. 관리자 및 관리자는 이전에 로그인 한 모든 세션을 무효화합니다 (단 하나만있는 경우).

내 web.xml에는 다음과 같이 정의되어 있습니다.

<listener>
 <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

내 봄 보안 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는 크롬에 한 번, 파이어 폭스에 한 번 두 번 로그인했습니다.

USER_A의 첫 번째 / 이전 로그인 세션을 완전히 무효화 / 파괴하는 방법에 대한 아이디어는 스프링 페이지 보안 페이지에 액세스하려고 시도 할 때 "이 사람의 세션이 유효하지 않거나 만료되었으므로 로그인 페이지로 보냅니다"라고 알 수 있습니다.

어떤 도움을 주셔서 감사합니다. 감사.

해결법

  1. ==============================

    1.거의 당신처럼 보이지만, 문제는 SessionRegistry에서 정보를 조기에 제거한다는 것입니다. ConcurrentSessionFilter는 사용자가 요청할 때 현재 세션에 대한 검사를 수행하고이 시점에서 만료 된 세션을 로그 아웃하고 무효화합니다. 해당 세션에 대한 정보를 이미 제거 했으므로 세션을 찾지 못하고 아무 것도하지 않습니다.

    거의 당신처럼 보이지만, 문제는 SessionRegistry에서 정보를 조기에 제거한다는 것입니다. ConcurrentSessionFilter는 사용자가 요청할 때 현재 세션에 대한 검사를 수행하고이 시점에서 만료 된 세션을 로그 아웃하고 무효화합니다. 해당 세션에 대한 정보를 이미 제거 했으므로 세션을 찾지 못하고 아무 것도하지 않습니다.

    다음 줄을 제거하십시오.

    sessionRegistry.removeSessionInformation(info.getSessionId());
    
  2. ==============================

    2.필요한 것은 equals () 및 hashCode ()를 수정하는 것뿐입니다. 코드가 나중에 실행됩니다. 도움이 될 수 있습니다. http://blog.trifork.com/2014/02/28/session-timeout-and-concurrent-session-control-with-spring-security-and-spring-mvc/

    필요한 것은 equals () 및 hashCode ()를 수정하는 것뿐입니다. 코드가 나중에 실행됩니다. 도움이 될 수 있습니다. http://blog.trifork.com/2014/02/28/session-timeout-and-concurrent-session-control-with-spring-security-and-spring-mvc/

  3. from https://stackoverflow.com/questions/22370819/how-to-log-a-user-out-programmatically-using-spring-security by cc-by-sa and MIT license