[동시 세션 제어]
스프링 시큐리티를 사용하다보면 세션은 유저의 인증인가 역활에 큰 역활을 한다.
하지만 이런경우 생각해보자.
1. 내 아이디를 다른 사람이 들어와서 세션을 발급받은 경우
만약 내가 쓰는 아이디가 있고 , 이 아이디를 현재 사용하고 있다.
하지만 내 아이디랑 비밀번호가 누군가에게 탈취당해서
내가 지금 해당 웹사이트를 사용하고 있는 와중에 누군가가 내 아이디로 인증을 받고
세션을 받아서 해당 웹사이트로 들어오게 되었다.
그럴경우 어떤식으로 이 방법을 해결할지가 동시 세션제어이다.
1. 만약 동시 세션이 들어왔다면 두 가지 해결방안이 있다.
1.이전 사용자 세션만료
만약에 user라는 아이디로 총 2명의 클라이언트가 들어왔다.
user : member1
user : member2 이렇게 가정을 해보자.
이럴 경우 세션이 동시에 두 개가 발급이 되었고 같은 아이디로 내 사이트에 접속중이다.
이럴 경우 이전 사용자를 세션을 만료 시키는 방식이 있다.
이 방식을 사용하면 user : member1
즉 제일 먼저 들어온 사용자의 세션을 만료 시켜 버리는 것 이다.
그렇게 된다면 member1의 세션은 만료가 되고 다시 인증이 필요한 사이트를 들어갈 때
인증을 받지 못하고 login페이지로 가게 될 것 이다.
이것이 이전 사용자 세션만료 방식이다.
2. 현재 사용자 인증 실패
아까 위에 처럼 내 아이디로 동시에 두명의 클라이언트가 들어왔다.
user : member1
user : member2
첫 번째 방식은 기존의 있는 사용자의 세션을 만료 시켜버리고
새 사용자의 세션을 유지시키는 방식을 사용하고 있는 반면에
두 번째 방식은 기존의 있는 사용자의 세션을 유지시키되
새 사용자는 같은 아이디로 들어올 수 없게 하는 것 이다.
메이플스토리를 한번 생각해보자.
마치 이러한 경우와 흡사하다고 생각하면된다.
기존 유저는 로그인이 되어있고
새 사용자가 들어올 때 새 사용자의 접근권한을 막아버리는 것 이다.
즉 이런식으로 새 사용자의 접근 권한을 막아 버린다.
어떠한 전략방식을 사용할지는 개발자의 판단에 따라 다르다.
그렇다면 어떤식으로 사용하는지 보도록 하자.
해당 api를 살펴보면 다음과 같다.
sessionManagement
Session의 방식을 설정 할 수 있게 해주는 메서드이다.
기본적으로 이 세션매니저 안에서 세션의 상태를 설정 할 수 있다.
maximumSessions()
세션의 갯수를 설정하는 것 이다.
만약 1이라고 한다면 아이디마다 세션은 1개씩 발급이된다.
하지만 user라는 아이디에 2명의 사용자(클라이언트)가 들어왔을 때는 세션은 2개가 발급이된다.
그럴 경우 세션의 갯수는 1개로 설정을 하였기 때문에 오류가 나게된다.
즉 한 아이디에 세션의 갯수를 몇개로 설정을 해놓을 것 인지 설정하는 메서드이다.
기본적으로는 1개를 설정해놓는다.
만약 한 계정에 세션을 무한대로 하고싶다면 -1로 설정하면 세션의 갯수는 무한대가 된다.
maximumSessions(1).maxSessionsPreventsLogin(true)
maxSessionPreventsLogin은 maximumSessios와 같이 사용하는 메서드이며
앞서 위에 설명했다 싶이 동시의 두명의 사용자가 들어왔을때 상태전략이다.
1. 이전 사용자의 세션을 만료할 것
2. 새 사용자의 접근권한을 막아버린다.
이 두가지의 상태전략을 가지고 있으며
maxSessionPreventsLogin에는 bool타입이 들어간다.
true일 경우 = 새 사용자(후속 사용자)가 동일 아이디로 들어올 때 오류를 터뜨림.
false일 경우 = 이전 사용자의 세션을 만료시켜서 접근권한을 없애버림
.invalidSessionUrl("/home")
invalidSessionUrl의 경우 세션이 유효하지 않을 때 어디로 리다이렉트 시킬 지 정하는 메서드이다.
즉 인증권한이 없을 때 해당 사용자를 설정한 url로 리다이렉트 시킨다.
expiredUrl("/home")
세션이 만료되었을 경우 설정할 메서드이다.
해당 사용자의 세션이 만료되었을 경우 설정한 url로 보낸다.
[세션 고정 공격]
그렇다면 우리는 세션 동시성 제어를 알아봤다.
그렇다면 세션 고정 보호는 무엇일까?
세션 고정 공격은 사용자가 있고 공격자가 있다고 하자.
만약 사용자가 어떤 웹사이트에 로그인을 했다.
userId : hi
password : 1234
로 로그인을 하였고
세션은 1234로 발급되었다.
하지만 어떤 공격자가 이 세션을 탈취해서 해당 세션을 해당 사용자마냥 사용할 수 있다.
이러한 방어정책으로 세션 고정 보호 정책이 있는데
세션 고정 보호 정책이란
기존의 세션의 id를 로그인을 할 때 마다 새로운 세션 id로 바꾸거나
새로운 세션을 발급해서 추정 할 수 없도록 하거나 탈취 당해도
해당 세션을 파기시키게끔 할 수 있는 정책이다.
그림으로 본다면 이런 느낌이다.
스프링 시큐리티에선 이런 세션 고정보호를 하기위해 기본적으로 설정이 되어있다.
해당 메서드를 보자면 이렇다.
sessionFixation().changeSessionId(
기존 세션에 있는 id를 바꿔 추정할 수 없도록 하는 메서드이다.
sessionFixation().none()
none으로 설정하게 된다면 해당 세션 보호정책을 끈다.
security.sessionManagement(manager -> manager.sessionFixation().newSession());
newSession은 로그인 시 기존에 있던 세션을 파기하고
새로운 세션으로 만들어서 발급한다.
[세션 정책]
그렇다면 세션정책은 무엇일까?
개발할때 세션이 필요할수도 있고 없을 경우도 있다.
예를들어 내가 만약 JWT 토큰을 사용한다면
세션을 사용하지 않음으로 세션은 필요가 없다.
즉 세션을 끄거나 킬 수 있는 전략이다.
security.sessionManagement(sessionConfig ->
sessionConfig.sessionCreationPolicy(SessionCreationPolicy.ALWAYS));
세션의 기능을 항상 사용한다.
security.sessionManagement(sessionConfig ->
sessionConfig.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED));
스프링 시큐리티가 세션을 필요 시 생성한다
이 설정은 스프링 시큐리티의 기본값으로 되어있다.
security.sessionManagement(sessionConfig ->
sessionConfig.sessionCreationPolicy(SessionCreationPolicy.NEVER));
스프링 시큐리티가 더 이상 세션을 만들지 않는다.
하지만 세션이 있는 경우 그 세션은 사용한다.
security.sessionManagement(sessionConfig ->
sessionConfig.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
세션을 만들지도 세션이 남아있어도 세션을 사용하지 않는다.
기본적으로 이러한 옵션은 토큰 방식의 인증 기반일 때 사용한다 ( 예 JWT 토큰)
'스프링 시큐리티 -세션 > Chatper01 스프링 시큐리티 전반적인 기능' 카테고리의 다른 글
[스프링 시큐리티 4장] ExceptionTranslationFilter , RequestCacheAwareFilter란 무엇인가? (1) | 2023.12.26 |
---|---|
2장 스프링 시큐리티 FormLogin 메서드와 동작 방식 (1) | 2023.12.24 |
1장 자바 스프링 시큐리티 구성 및 의존성 추가 기능들 (0) | 2023.12.24 |