티스토리 뷰

728x90

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;
}

질문

인프런 질답 게시판에 누군가 정리해두신게 있어서 첨부

Truestar 님

답변

더보기

네 잘 정리하신 것 같습니다.

스프링 시큐리티에서 익명사용자의 개념을 별도의 기능으로 구조화 했다고 보시면 될 것 같습니다.

그렇지만 로그인 인증을 받지 못한 사용자이기 때문에 실질적으로 아무런 권한을 갖지 못하는 사용자로 보셔도 무방합니다.

그래서 스프링 시큐리티 내부적으로 익명사용자를 인증사용자와 구분하기 위해 독립적인 객체를 만들어 익명사용자임을 나타내는 여러 군데의 코드가 존재합니다.

그리고 익명사용자의 역할과 기능이 스프링 시큐리티에서 큰 비중을 차지하는 것은 아니기 때문에 간단한 개념정도 이해하시고 사용하시면 될 것 같습니다.

감사합니다.

다른내용

더보기

이건 다른 답변 달으신 글인데 이해가 잘 된다. 나처럼 익명 사용자라는게 왜 있어야 되는건가 라는 것에 대한 질문

 

스프링 시큐리티 설계자가 왜 익명사용자라는 개념을 도입했는지 생각해보면 될 것 같습니다.

인증을 하지 않은 사용자를 단지 user 객체가 null 이라는 단순한 개념이 아닌 AnonymouAuthenticationToken 객체에  익명사용자의 정보를 저장하고(사용자명, 권한, 인증여부 등..) 이를 SecuirtyContext 객체에 저장하여 어플리케이션 전역적으로 사용할 수있도록 도입했을 뿐입니다.

즉, 익명사용자일 경우

String user = SecurityContextHolder.getContext().getAuthentication() 하면 user 에 "anonymousUser" 가 저장되고 이 user 변수는 principal 에 저장이 되며 principal 은 AnonymousAuthenticationToken 저장이 되고 최종적으로 AnonymusAuthenticationToken 은 SecurityContext 에 저장이 되는 계층적 구조로 되어 있습니다.

이건 인증사용자도 마찬가지 구조입니다.

이러한 전반적인 처리를 하는 필터가 AnonymousAuthenticationFilter 이구요

어떻게 보면 객체지향적인 설계사상에 근거하여 익명사용자도 인증사용자처럼 일관성, 통일성 있게 스프링 시큐리티의 인증 프로세스를 따르도록 구현한 것일 수도 있습니다.

굳이 스프링 시큐리티가 아니라도 만약 어떤 시스템에서 인증을 하지 않는 사용자를 어떤 특정한 클래스를 만들어 거기에 보관하여 관리하도록 설계를 하고 구현 한다면 위와 비슷한 개념이 됩니다.

너무 어렵게 접근하실 필요는 없습니다

일반적으로 우리가 아는 로그인 하지 않은 사용자의 개념을 조금 더 구조적으로  설계하고 필터개념을 도입해서 관리하고자 함이라고 이해하시면 됩니다.

참고

https://www.inflearn.com/course/%EC%BD%94%EC%96%B4-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/

 

스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 인프런 | 강의

초급에서 중.고급에 이르기까지 스프링 시큐리티의 기본 개념부터 API 사용법과 내부 아키텍처를 학습하게 되고 이를 바탕으로 실전 프로젝트를 완성해 나감으로써 스프링 시큐리티의 인증과

www.inflearn.com

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함