티스토리 뷰
AnonymousAuthenticationFilter 익명 사용자를 위한 필터
처음 강의를 들을때 부터 익명 사용자? 이게 왜 필요한거지 하면서 들었던 기억이 난다.
이 필터가 하는 일은 많지는 않다.
보통 사용자가 인증을 받게되면 세션에 인증을 받은 유저 객체를 저장하고 다시금 사용자가 페이지에 접근하게되면 세션에 유저 객체가 null이 아니면 인증을 받은 사용자라고 하고 null이면 인증을 받지 않은 사용자라고 한다.
AnonymousAuthenticationFilter는 익명사용자와 인증 사용자를 구분해서 처리하기 위한 용도로 사용
클라이언트가 request 요청이 들어오면 인증객체가 있는지 SecurityContext 에서 확인한다.
만약 있다면 다음 필터로 넘어가고 아니라면 익명사용자용 인증객체인 AnonymousAuthenticationToken을 사용해서 SecurityContext에 익명사용자용 객체를 저장한다. (null로 저장하는 것이 아님)
테스트를 위한 인가정책과 인증정책 configure
@Override
protected void configure(HttpSecurity http) throws Exception {
//인가정책
http
.authorizeRequests()
.anyRequest().authenticated();
//인증정책
http
.formLogin();
}
AnonymousAuthenticationFilter 내부
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
Authentication authentication = createAuthentication((HttpServletRequest) req);
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.of(() -> "Set SecurityContextHolder to "
+ SecurityContextHolder.getContext().getAuthentication()));
}
else {
this.logger.debug("Set SecurityContextHolder to anonymous SecurityContext");
}
}
else {
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.of(() -> "Did not set SecurityContextHolder since already authenticated "
+ SecurityContextHolder.getContext().getAuthentication()));
}
}
chain.doFilter(req, res);
}
SecurityContextHolder.getContext().getAuthentication() == null
인증객체가 null인지 아닌지 검사하는 소스
맨 처음 접근하면 인증객체가 null이므로 익명사용자용 AnonymousAuthenticationToken 객체를 만들어서 기본적인 정보를 담아서 Security Context에 저장한다.
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken(this.key, this.principal,
this.authorities);
token.setDetails(this.authenticationDetailsSource.buildDetails(request));
return token;
}
질문
인프런 질답 게시판에 누군가 정리해두신게 있어서 첨부
답변
네 잘 정리하신 것 같습니다.
스프링 시큐리티에서 익명사용자의 개념을 별도의 기능으로 구조화 했다고 보시면 될 것 같습니다.
그렇지만 로그인 인증을 받지 못한 사용자이기 때문에 실질적으로 아무런 권한을 갖지 못하는 사용자로 보셔도 무방합니다.
그래서 스프링 시큐리티 내부적으로 익명사용자를 인증사용자와 구분하기 위해 독립적인 객체를 만들어 익명사용자임을 나타내는 여러 군데의 코드가 존재합니다.
그리고 익명사용자의 역할과 기능이 스프링 시큐리티에서 큰 비중을 차지하는 것은 아니기 때문에 간단한 개념정도 이해하시고 사용하시면 될 것 같습니다.
감사합니다.
다른내용
이건 다른 답변 달으신 글인데 이해가 잘 된다. 나처럼 익명 사용자라는게 왜 있어야 되는건가 라는 것에 대한 질문
스프링 시큐리티 설계자가 왜 익명사용자라는 개념을 도입했는지 생각해보면 될 것 같습니다.
인증을 하지 않은 사용자를 단지 user 객체가 null 이라는 단순한 개념이 아닌 AnonymouAuthenticationToken 객체에 익명사용자의 정보를 저장하고(사용자명, 권한, 인증여부 등..) 이를 SecuirtyContext 객체에 저장하여 어플리케이션 전역적으로 사용할 수있도록 도입했을 뿐입니다.
즉, 익명사용자일 경우
String user = SecurityContextHolder.getContext().getAuthentication() 하면 user 에 "anonymousUser" 가 저장되고 이 user 변수는 principal 에 저장이 되며 principal 은 AnonymousAuthenticationToken 저장이 되고 최종적으로 AnonymusAuthenticationToken 은 SecurityContext 에 저장이 되는 계층적 구조로 되어 있습니다.
이건 인증사용자도 마찬가지 구조입니다.
이러한 전반적인 처리를 하는 필터가 AnonymousAuthenticationFilter 이구요
어떻게 보면 객체지향적인 설계사상에 근거하여 익명사용자도 인증사용자처럼 일관성, 통일성 있게 스프링 시큐리티의 인증 프로세스를 따르도록 구현한 것일 수도 있습니다.
굳이 스프링 시큐리티가 아니라도 만약 어떤 시스템에서 인증을 하지 않는 사용자를 어떤 특정한 클래스를 만들어 거기에 보관하여 관리하도록 설계를 하고 구현 한다면 위와 비슷한 개념이 됩니다.
너무 어렵게 접근하실 필요는 없습니다
일반적으로 우리가 아는 로그인 하지 않은 사용자의 개념을 조금 더 구조적으로 설계하고 필터개념을 도입해서 관리하고자 함이라고 이해하시면 됩니다.
참고
- Total
- Today
- Yesterday
- jQuery
- mybatis config
- Linux
- input
- window
- svn
- LocalDateTime
- Github Status
- 베리 심플
- maven
- Java
- springboot
- Bash tab
- rocky
- mybatis
- LocalDate
- docker
- 오라클
- 북리뷰
- JavaScript
- elasticsearch
- oracle
- Spring Security
- localtime
- Spring
- Kotlin
- intellij
- Mac
- config-location
- 프로페셔널 스튜던트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |