익명 인증 사용자

황상익·2024년 9월 9일

security

목록 보기
3/16

<익명 인증 사용자>

익명 사용자

익명으로 인증된 사용자, 인증되지 않은 사용자, → 단지 액세스 제어 속성을 구성하는 편리한 방법 제공

→ 인증 받은 사용자와 인증 받지 않은 사용자를 객체를 따로 구분 , 익명 사용자는 세션에 사용하지 않겠다. 인증 받지 않은 상태를 그대로 유지함. 인증 사용자도, 익명 사용자도 SpringSecurity 안에 저장하겠다. 인증 유무를 → session으로 가져온다.

SecurityContextHolder, Authentication 객체를 포함하고, (session)에서 판단 null을 포함하지 않다는다는 것을 규칙을 세우게 되면 클래스를 더 견고하게 작성 가능
인증 사용자와 익명 인증 사용자를 구분, → 어떤 기능을 수행하고자 할때 유용하게 사용 가능, 익명 인증 객체를 세션에 저장하지 않는다.
익명 인증 사용자의 권한을 별도로 운용할 수 있다. 즉 인증된 사용자가 접근할 수 없도록 구성 가능.

@Bean

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http

.authorizeHttpRequests( auth -> auth.anyRequest().authenticated())
.formLogin(Customizer.withDefaults())
.anonymous(anonymous -> anonymous
<AnonymousAuthenticationFilter  AnonymousAuthenticationToken> 따로 발행

.principal("guest") 

.authorities("ROLE_GUEST")
);

return http.build();
}

익명 사용자도 이름을 변경 가능, 권한에 대해서도 변경 가능

  • 스프링 MVC에서 익명 인증 사용

HttpServletRequest#getPrincipal을 사용하여 파라미터를 해결
인증을 받지 못한 사용자가 요청 → null

public String method(Authentication authentication) {
if (authentication instanceof AnonymousAuthenticationToken) {

return "anonymous";
}else{

return "not anonymous";
}

}

- 익명 요청에서 Authentication을 획득 하고 싶다면, @CurrentSecurityContext를 사용 (익명사용자의 값을 얻고 싶다면)

public String method(@CurrentSecurityContext SecurityContext context){ 

return context.getAuthentication().getName();

}
  • AnonymousAuthenticationFilter
    SecurityContextHolder → Authentication 객체 없을 경우 → null
    client → AnonymousAuthenticationFilter -null ≠ Yes→ chain.doFilter
    //필터 이전에 이미 인증이 되었다면 굳이 토큰을 생성할 필요 없다.

<인증 되지 않은 사용자도 null로 두지 않겠다>
client → AnonymousAuthenticationFilter - null == No→ AnonymousAuthenticationToken (Authentication을 SecurityContext)에 설정 → SecurityContextHolder → AnonymousAuthenticationToken

@Configuration
@EnableCaching
public class SecurityConfig {

    //메모리 상에서 사용자 설정
    //설정 파일과 중복이 있다면, @Bean 인메모리 방식이 우선
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {

        //User객체는 SpringSecurity가 갖고 있는 User
        UserDetails user = User.withUsername("user")
                .password("{noop}1111") //(noop)을 사용하면 평서문 처럼 사용 가능
                .authorities("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http
                //SecurityFilterChainConfiguration -> filter 조건 성립 안됨
                //SecurityFilterChain -> Bean을 생성했기 때문 -> Bean이 없을 경우에만 성립된다. -> 사용자가 설정한 쪽으로 오게 된다.
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/logoutSuccess").permitAll()
                        .anyRequest().authenticated())
                .formLogin(Customizer.withDefaults())
                //.csrf(csrf -> csrf.disable()) //csrf 방식이 disable -> post 방식 뿐만 아니라 get 방식도 적용이 가능
                .logout(logout -> logout
                        .logoutUrl("/logout")
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST")) //get 방식도 가능
                        .logoutSuccessUrl("/logoutSuccess") // 해당하는 Mapping 생성 logoutRequestMatcher 처리 안하면 post 방식만 가능
                        .logoutSuccessHandler(new LogoutSuccessHandler() {
                            @Override
                            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                                response.sendRedirect("/logoutSuccess");
                                //복잡한 경로 -> handler 사용 
                            }
                        })
                        .deleteCookies("JSESSIONID", "remember-me") //보통적으로 JSESSIONID는 삭제
                        .invalidateHttpSession(true) // logout시 session 무효화
                        .clearAuthentication(true) //securityContext 안에 있는 authentication 객체를 제거
                        .addLogoutHandler(new LogoutHandler() {
                            @Override
                            public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
                                //세션 무효화
                                HttpSession session = request.getSession();
                                session.invalidate();
                                //시큐리티 컨택스트 안에있는 authentication을 제거 가능 / 기존 authenticaiton 객체가 제거
                                SecurityContextHolder.getContextHolderStrategy().getContext().setAuthentication(null);
                                SecurityContextHolder.getContextHolderStrategy().clearContext(); //SecurityContextHolder 또한 clear
                            }
                        })

                        .permitAll() //logoutProc
                );


        return http.build(); // securityFilterChain 생성된다.
    }
}
profile
개발자를 향해 가는 중입니다~! 항상 겸손

0개의 댓글