복붙노트

[SPRING] Spring Security maxSession이 작동하지 않습니다.

SPRING

Spring Security maxSession이 작동하지 않습니다.

사용자가 최대 세션 수를 초과하면 로그인을 방지하고 싶습니다. 예를 들어 모든 사용자는 한 번만 로그인 할 수 있습니다. 그리고 나서 로그인 한 사용자가 다른 로그인 시스템을 시도하면 로그인을 비활성화해야합니다.

.sessionManagement()
.maximumSessions(1).expiredUrl("/login?expire").maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry());


@Bean
public static ServletListenerRegistrationBean httpSessionEventPublisher() {
    return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}

해결법

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

    1.참고 : 이것은 스프링 MVC와 4.3.9에서 테스트되었습니다. 릴리즈, 아직 스프링 부트를 사용하지 않았습니다.

    참고 : 이것은 스프링 MVC와 4.3.9에서 테스트되었습니다. 릴리즈, 아직 스프링 부트를 사용하지 않았습니다.

    솔루션을 찾았는데 어떻게 작동하는지 나와 공유하겠습니다.

    1) 다음과 같이 SessionManagement로 HttpSecurity를 ​​구성했습니다.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http
        .authorizeRequests()
          .antMatchers("/resources/**").permitAll()
          .antMatchers("/login**").permitAll()        // 1
          .antMatchers(...)
          .anyRequest().authenticated()
          .and()
        .formLogin()
          .loginPage("/login")
          .permitAll()
          .and()
        .logout()
          .deleteCookies("JSESSIONID")
          .permitAll()
          .and()
        .sessionManagement()                          // 2
          .maximumSessions(1)                         // 3
            .maxSessionsPreventsLogin(false)          // 4
            .expiredUrl("/login?expired")             // 5
            .sessionRegistry(getSessionRegistry())    // 6
        ;           
    }
    

    Spring Doc> HttpSecurity> sessionManagement () 문서의 도움으로,

    sessionManagement (), maximumSessions (1), 물론 expiredUrl ( "/ login? expired")이 필요한 이유를 알 수 있습니다.

    2) 실제로 현재 로그인 한 사용자 또는 expireNow () 특정 세션에 액세스해야하는 경우 getSessionRegistry ()가 필요할 수도 있지만 maximumSessions (1)가 없으면 정상적으로 작동합니다.

    다시 의사의 도움으로

    그래서 내 SecurityWebInitializer.java 클래스에서 override override enableHttpSessionEventPublisher ()를 변경해야합니다.

    public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
        @Override
        protected boolean enableHttpSessionEventPublisher() {
            return true;
        }
    }
    

    3) 이제 마지막으로 발견 한 것이 내 문제였습니다.   Spring 프레임 워크에서 새로운 기능이기 때문에 사용자 정의 UserDetails를 수행하는 방법을 배웠지 만 구현이 좋지 않지만 나중에 더 잘 수행 할 수 있습니다. Entity와 UserDetails 모두 역할을하는 Entity를 작성했습니다.

        @Entity
        @Component("user")
        public class User implements UserDetails, Serializable {
            private static final long serialVersionUID = 1L;
    
            // ...
    
            @Override
            public boolean equals(Object obj) {
                if (obj instanceof User) {
                  return username.equals( ((User) obj).getUsername() );
                }
                return false;
            }
    
            @Override
            public int hashCode() {
                return username != null ? username.hashCode() : 0;
            }
        }
    

    몇 년 전에이 포럼에서 hashCode () equals () 메소드를 모두 구현해야한다는 것을 알았습니다. UserDetails User.java의 기본 구현 소스 코드를 살펴보면 두 가지가 모두 있다는 것을 알게 될 것입니다 구현 된 메소드, 나는 그것을했고 그것은 매력처럼 작동했습니다.

    그래서 그게 도움이되기를 바랍니다.

    이 링크도 읽을 수 있습니다. Spring - 사용자의 모든 세션 만료

  2. from https://stackoverflow.com/questions/37892563/spring-security-maxsession-doesnt-work by cc-by-sa and MIT license