해결된 질문
작성
·
343
·
수정됨
0
안녕하세요 강사님
강의 내용을 듣고 제가 이해한 부분이 맞는지 여부와
추가적으로 질문드리고 싶은 내용이 있습니다.
유저가 최초 로그인을(인증) 하게 되면
SecurityContextPersistenceFilter에 HttpSessionSecurityContextRepository를 통해 SecurityContext를 생성하고
UsernamePasswordAuthenticaionFilter에서 인증 처리를 거친 후에
SecurityContextPersistenceFilter에서 Session에 저장하여 SecurityContext를 저장한다.
인증 이후에 유저가 요청하게 되면
SecurityContextPersistenceFilter에 HttpSessionSecurityContextRepository를 통해 Session에서 SecurityContext를 가져와서
SecurityContextHolder에 저장한다.
우선 제가 이해한 부분은 이렇습니다.
맞게 이해했는지 궁금합니다.
그리고 여기서 추가로 여쭤보고 싶은 점이
1. SecurityContextPersistenceFilter에 설명 강의 부분에서
최종 응답 시 공통 로직으로 SecurityContextHolder에서 clearContext()를 한다고 설명해주셨는데
SecurityContextHolder를 clear하지 않고 유지해야 Authentication객체를 계속 유지하는 게 아닌지 궁금합니다.
또한 로그인한 유저 객체를 가져올 때
SecurityContextHolder.getContext().getAuthentication()을 통해서 가져오는데
최종 응답 시에 clearContext()를 한다면 어떻게 가져오는지 궁금합니다.
2. ajax 방식을 연습할 겸 따로 프로젝트를 만들어서 진행해봤습니다.
거기서 FormLogin방식 자체를 사용하지 않았더니 filterChainProxy에 UsernamePasswordAuthenticationFilter 자체가 등록되지 않는 것 같습니다.
UsernamePasswordAuthenticationFilter는 FormLogin 방식에서만 등록되는 필터인가요?
그리고 인증 이후 SecurityContextPersistenceFilter에서 SecurityContextHolder에 값을 저장하는 로직이 궁금합니다.
자체 필터를 등록하고
해당 필터에서 HttpSession에 SecurityContext key("SPRING_SECURITY_CONTEXT")로 authentication을 저장해도
SecurityContextPersistenceFilter에서 SecurityContextHolder에 SecurityContext를 설정하지 않는 것 같습니다.
답변 1
1
네
처음 질문하신 내용은 잘 이해하고 계십니다.
SecurityContextHolder 에 SecurityContext 가 저장되는 원리 및 흐름을 인증 시점과 인증 이후 시점으로 구분해서 이해하시면 됩니다.
그리고
SecurityContextHolder 에 저장된 SecurityContext 는 SecurityContextHolder.clear() 하기 전에 이미 Session 에 저장되어 있는 상태입니다. 그렇기 때문에 SecurityContextHolder.clear() 하더라도 상관이 없으며 사용자가 요청을 다시 하더라도 세션에 저장되어 있는 SessionContext 를 가져올 수 있기 때문에 Authentication 또한 참조가 가능합니다.
참고로 알아두실 것은 SecurityContextHolder 에 저장된 SecurityContext 객체는 내부적으로 스레드마다 할당된 저장소인 ThreadLocal 에 저장되어 있습니다. 그래서 사용자의 요청이 완료되고 다시 사용자의 요청이 시작되면 이전의 스레드가 아닌 새로운 스레드가 할당되기 때문에 SecurityContextHolder 에 있는 ThreadLocal 에 SecurityContext 객체를 계속 유지할 필요가 없습니다. 그래서 SecurityContextHolder.clear() 하는 것이 맞습니다.
네 맞습니다. UsernamePasswordAuthenticationFilter 는 formLogin() 를 설정할 경우에만 생성되는 필터입니다.
그리고 아래 코드는 SecurityContextPersistenceFilter 일부 인데
SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder);
try {
SecurityContextHolder.setContext(contextBeforeChainExecution);
SecurityContextHolder.setContext() 가 실행되고 있습니다. 즉 세션에서 가지고 오거나 혹은 새로 생성된 SecurityContext 를 SecurityContextHolder 에 저장하고 있습니다.
궁금한 점이 이해가 됐습니다.
친절한 설명 감사합니다