[Spring Boot] Spring Security maximumSessions 관련

2018. 6. 8. 16:50·Development/Java
반응형

spring boot security(라고 쓰고, spring security 라고 읽을 수도 있다) 에서 동시접속 세션수를 제한하는 기능이 있다.




@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(true)
    }

}


위와 같이 @Configuration에 @EnableWebSecurity 어노테이션을 붙인 뒤, WebSecurityConfigurerAdapter를 상속받아 구현하면 된다.


override된 메서드 중 confiugre() 함수 내에 http security를 설정할 수 있는데


maximumSessions(1)을 주게 되면 해당 UserDetails에 해당하는 유저가 "1명" 만 접속이 가능하다.


이론상으론 그런데, "Maximum sessions of 1 for this principal exceeded" 와 같은 에러를 뿜고 작동이 잘 안된다.


스텝

  1. /login 페이지에서 A유저로 로그인을 진행
  2. /logout 페이지로 이동해서 로그아웃을 진행
  3. /login 페이지에서 다시 동일한 A유저로 로그인을 진행
하게 되면 세션이 이미 있어서 초과되었다는 에러와 함께 로그인이 되지 않는다.

도대체 왜 이렇게 구현이 되어있는지는 알 수가 없는데, 검색해본 결과 뭐.. spring security의 버전을 올려서 해결했다.. 현상이 이렇다 라고는 하는데

구체적인 해결방안이 없어서 구글링을 하던 도중 해결책을 찾아냈다.




@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 최대 세션 수 설정
        http.sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(true)
                .expiredUrl("/duplicated-login")
                .sessionRegistry(sessionRegistry);
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }// Register HttpSessionEventPublisher

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

}


위와 같이 SessionRegistry와 ServletListenerRegistrationBean을 Bean으로 만들면 된다.


SessionRegistry는 http의 sessionManagement에 직접 붙여주고, ServletListenerRegistrationBean는 그냥 Bean만 생성을 하면 된다.(static bean)


이렇게 설정을 하니 동일 유저로 로그인/로그아웃을 진행해도 문제없이 잘 된다.

+ 접속한 브라우저 말고 크롬 시크릿 페이지를 열어서 다른 세션으로 접속을 시도해도 한 User가 로그인이 되어 있으면 로그인이 되지 않게 된다.


또한 UserDetails를 구현한 구현체에 반드시 equals, hashcode 메서드를 override해서 구현을 해줘야 한다.


본인은 Lombok을 사용하기 때문에 




@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "username")
public class User implements Principal, UserDetails {
    @Id
    @Column
    @JsonIgnore
    private String username;

    @Column
    @JsonIgnore
    private String password;

    @Column
    @JsonIgnore
    private String authorities;

    @Column
    private boolean locked;

    @Column
    @JsonIgnore
    private String ip;

    @Column
    @JsonIgnore
    private String userAgent;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date creation;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastAccess;

    @Override
    public String getName() {
        return username;
    }

    @Override
    public Collection getAuthorities() {
        List authorityList = new ArrayList<>();
        if (!StringUtils.isEmpty(authorities)) {
            String[] splitedValue = authorities.split(",");
            for (String auth : splitedValue) {
                authorityList.add(new SimpleGrantedAuthority(auth));
            }
        }
        return authorityList;
    }

    @Override
    public String getUsername() {
        return this.username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}


와 같이 사용한다. (username 기준으로 equals, hashcode를 생성)

반응형
저작자표시 동일조건 (새창열림)

'Development > Java' 카테고리의 다른 글

[Spring boot] Websocket connect / disconnect 관련  (0) 2018.06.08
[Spring Boot] Resource load 관련  (0) 2018.06.08
SpringBoot Jackson(ObjectMapper) Config  (0) 2017.07.07
[Spring] @Valid Collection Validation 관련  (3) 2017.06.22
[Framework] Light4J(light-java)  (0) 2017.05.28
'Development/Java' 카테고리의 다른 글
  • [Spring boot] Websocket connect / disconnect 관련
  • [Spring Boot] Resource load 관련
  • SpringBoot Jackson(ObjectMapper) Config
  • [Spring] @Valid Collection Validation 관련
@곰팡
@곰팡
Java Backend Developer
  • @곰팡
    곰팡이 먼지연구소
    @곰팡
  • 전체
    오늘
    어제
    • 분류 전체보기 (55)
      • Daily Life (1)
        • 잡담 (1)
      • IT기업 입사 (0)
      • Development (52)
        • Java (24)
        • Spring (6)
        • Web (3)
        • OS (6)
        • Algorithm (4)
        • 이것저것 끄적끄적 (3)
        • Netty & FlatBuffers (3)
        • Database (2)
        • Dev-ops, Monitoring (1)
      • Labatory (0)
        • Test Bed 1 (0)
  • 블로그 메뉴

    • 메인
    • 카테고리
    • 태그
    • 방명록
    • 글 작성
    • 관리자
  • 링크

    • linkedIn
    • github
  • 공지사항

  • 인기 글

  • 태그

    일본여행
    HashMap
    고쿠라역
    linux
    기타큐슈
    prometheus
    일본
    고쿠라
    springboot
    kitakyusu
    flatbuffer
    北九州
    북큐슈
    Spring
    해외여행
    자바
    java
    타코야끼
    皿倉山
    Spring Boot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
@곰팡
[Spring Boot] Spring Security maximumSessions 관련
상단으로

티스토리툴바