SecurityContextHolder 관련 질문이 있습니다!
1431
작성한 질문수 53
안녕하세요.
항상 좋은 강의 감사드립니다!
SecurityContextholder 관련 질문이 있어 글을 적게 되었습니다.
SecurityContext는 ThreadLocal 기반이고, 이를 전역에서 사용할 수 있도록 Static 변수인 SecurityContextHolder에 저장된다고 이해를 했습니다. (강의 내용을 참고, 혹시.. SecurityContextHolder가 Static 변수가 아니라면 정정해주시면 감사하겠습니다!)
여기서 궁금한 부분은... 멀티 쓰레딩 환경입니다.
스프링 MVC는 결국 요청마다 쓰레드가 할당되는 쓰레딩풀 환경이라 멀티 쓰레드로 동작을 하고 있는 것으로 알고 있습니다.
그렇다면 동시에 사용자로부터 인증 요청이 온다면, 동시에 SecurityContextHolder에 SecurityContext가 각각 저장된다는 것인데.. 이런 환경에서 어떻게 동작하는지 잘 이해하기가 어렵습니다.
예를 들어 동시에 인증 요청이 오게 되면, SecurityContextHolder의 동시성 문제는 어떻게 처리되는 걸까요?
항상 좋은 강의 감사드립니다
좋은 하루 되세요!
답변 1
7
네
SecurityContextHolder 은 SecurityContext 를 ThreadLocal 에 저장하고 있습니다.
SecurityContextHolder 는 전략패턴에 따라 기본값은 ThreadLocalSecurityContextHolderStrategy 클래스를 사용합니다.
final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal();
ThreadLocalSecurityContextHolderStrategy() {
}
public void clearContext() {
contextHolder.remove();
}
public SecurityContext getContext() {
SecurityContext ctx = (SecurityContext)contextHolder.get();
if (ctx == null) {
ctx = this.createEmptyContext();
contextHolder.set(ctx);
}
return ctx;
}
......
.....
}
코드를 보시면 contextHolder 가 ThreadLocal 이고 contextHolder.get() 과 contextHolder.set(ctx) 를 통해 SecurityContext 객체를 저장하고 있습니다.
여기서 ThreadLocal 내부를 잠시 들여다 보겠습니다.
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
ThreadLocal 의 get() 메소드인데 보시면 현재 접속해 있는 Thread 를 참조합니다.
즉 각 사용자에게 할당된 스레드입니다.
그리고 각 스레드마다 고유하게 할당된 ThreadLocal 인 this 를 키로 해서 어떤 값(여기서는 SecurityContext) 를 얻고 있습니다.
그리고 set() 메소들입니다.
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value);
}
}
역시 현재 접속해 있는 스레드를 참조하고 해당 스레드만 가지고 있는 TheadLocal 인 this 를 키로 해서 어떤 값 즉 SecurityContext 를 맵에 저장하고 있습니다.
그렇기 때문에 비록 SecurityContextHolder 가 static 한 ThreadLocal 를 참조하고 있지만 ThreadLocal 내부적으로는 각 스레드마다 자신만의 ThreadLocal 을 키로 해서 SecurityContext 값을 저장 및 조회하고 있기 때문에 스레드에 안전하게 됩니다.
시큐리티 공부 버전 질문
0
178
1
[해결 방법] MethodSecurityConfig.customMethodSecurityMetadataSource() 호출하지 않는 이슈
0
187
1
AbstractSecurityInterceptor.class.beforeInvocation()를 2번 실행하는 경우
0
179
1
강의 코드가 왜이렇게 뒤죽박죽인가요...
0
255
1
메인 페이지로 접속해도 login url로 리다이렉트가 되지 않습니다..
0
239
1
파라미터값이 넘어가지 않습니다 ....
0
376
1
security filterChain 설정 질문이 있습니다.
0
332
1
소스 부분 질문 드립니다.
0
210
2
섹션4 7번 강의 문제가 있는거 같네요.
0
345
2
파일이 수시로 이름이 바껴있네요 ㄷㄷ
0
306
1
HttpSessionSecurityContextRepository를 사용안하는 문제
0
557
2
error , exception 이 잘 안됩니다.
0
284
2
thymeleaf tag 질문합니다.
0
198
2
버전업하면서 deprecated된 것들이 너무많아요
0
478
1
spring security 패치 관련
0
438
1
모바일을 사용할때 토큰말고 세션
0
853
2
DB 연동한 인가 부분에 대한 질문입니다!
0
265
1
Ajax방식도 똑같이 Session방식을 사용하는건가요?
0
308
1
Config 파일 생성 시 질문이 있습니다.
0
228
1
강사님 몇일동안 구글 검색만 100개 했는데도 이유를 모르겠습니다..
1
435
2
403 에러 뜹니다.
0
813
2
login_proc의 존재에 대한 간략한 설명입니다
0
277
1
top.html에 로그인 링크를 만들어서 로그인을 해봤습니다
0
288
2
안녕하세요. DB에 저장될 때 이해 안 가는 값이 있어서 질문드립니다!
0
192
1





