익명 인증 anonymous()

정민교·2024년 7월 14일
0

spring security

목록 보기
7/13
post-thumbnail

📒목표

익명 인증 사용자에 대해서 알아보고 전체적인 흐름을 확인한다.

📒개요

✔️익명사용자

스프링 시큐리티에서는 "인증되지 않은 사용자"를 "익명으로 인증된 사용자"로 취급하고 있으며, 이는 액세스 제어 속성을 구성하는데 더 편리하게 하기 위함이다.

SecurityContextHolder가 항상 Authenticaion 객체를 포함하고 null을 포함하지 않는다는 규칙을 세우게 되면 클래스를 더 견고하게 작성할 수 있다.

즉, 인증 받은 사용자나, 인증 받지 않은 사용자나 둘 다 객체를 생성해서 구분하고 관리하겠다는 의미다.

그리고 인증 받은 사용자는 인증 객체를 SecurityContext에 저장하고 이를 세션에도 저장했지만, 익명 인증 사용자는 SecurityContext에 저장하지만 세션에 SecurityContext를 저장하지 않는다.

익명 사용자 또한 객체로 관리하기 때문에 익명 사용자의 권한을 별도로 설정할 수 있어, 인증 받은 사용자는 접근할 수 없는 리소스를 별도로 구성이 가능하다.

그러니까 보통 인증을 시도하면 요청으로부터 받은 credentials를 가지고 유효한 회원인지 확인하고, 유효하다면 회원 정보를 세션에 저장한다.

그런데 유효한 회원이 아니라면 세션에 회원 정보를 null로 저장하고, 인증받지 못한 회원이구나 판단해도 되지만, spring security에서는 인증 받지 못한 사용자를 위한 클래스도 구성해서 인증을 받은 사용자, 익명 사용자를 둘 다 객체로 구분하고 관리하는 것을 목적으로 한다.

✔️익명 사용자 인증 api

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequest(auth -> auth.anyRequest().authenticated())
        .formLogin(Customizer.withDefaults())
        .anonymous(anonymous -> 
            //익명 사용자의 username을 설정한다.
            anonymous.principal("guest")
            
            //익명 사용자의 권한을 설정한다.
            anonymous.authorities("ROLE_GUEST")
    );
    return http.build();
}

AnonymousAuthenticationFilter는 인증 받지 못한 익명 사용자를 처리하는 필터다.

여기서 AnonymousAhtuenticaionToken을 생성하고 이 토큰 안에 기본적으로 username은 "anonymousUser", role은 "ROLE_ANONYMOUS"로 설정되어있다.

principal메소드로 username을 설정할 수 있고, authorities메소드로 role을 설정할 수 있다.

✔️스프링 MVC에서 익명 인증 사용하기

  • 스프링 MVC에서 요청 핸들러 메소드에 파라미터를 Authentication 타입으로 선언하면 HttpServletRequest 객체의 getPrincipal 메소드를 사용하여 파라미터를 해결한다.
public String method(Authentication authentication) {
    //authentication == null
    ...
}

이 때 authentication 파라미터의 값이 익명 사용자일 경우 null로 값이 들어오게 된다.

인증된 사용자라면 인증된 사용자 정보를 AuthenticationToken 타입의 객체를 값으로 받게된다.

  • 익명 요청에서 Authenticaion 객체를 얻기 위해서는 @CurrentSecurityContext 어노테이션을 파라미터에 사용하면 CurrentSecurityContextArgumentResolver가 동작하여 요청 파라미터를 처리한다.
public String method(@CurrentSecurityContext SecurityContext context) {
    return context.getAuthentication().getName();
}

✔️AnonymousAuthenticationFilter

AnonymousAuthenticationFilter는 익명 사용자인 경우를 처리하는 필터다.

인증받지 않은 사용자가 요청할 때 SecurityContextAuthentication객체는 null이다.

이 경우에 AnonymousAuthenticationFilter를 만날 때, AnonumousAuthenticationToken을 생성하고 SecurityContext에 저장한 후에 이 SecurityContextSecurityContextHolder에 저장한다.

하지만, AnonymousAuthenticationFilter는 요청이 이 필터에 도달하기 전에 인증받은 경우라면 아무 동작도 하지 않는다.

익명 사용자인 경우를 처리하는 필터이기 때문이다.

즉, Authentication이 null인지 아닌지를 체크한 후 동작하는 필터다.

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/anonymous").hasRole("GUEST")
                        .requestMatchers("/anonymousContext", "/authentication").permitAll() //익명 사용자를 참조하는 방법
                        .anyRequest().authenticated() //모든 요청은 인증을 받은 상태에서만 가능하도록 설정
                )
                .formLogin(Customizer.withDefaults())
                .anonymous(httpSecurityAnonymousConfigurer -> httpSecurityAnonymousConfigurer
                        .principal("guest")
                        .authorities("ROLE_GUEST")
                );

        return http.build();
    }
profile
백엔드 개발자

0개의 댓글