<익명 인증 사용자>
익명 사용자
익명으로 인증된 사용자, 인증되지 않은 사용자, → 단지 액세스 제어 속성을 구성하는 편리한 방법 제공
→ 인증 받은 사용자와 인증 받지 않은 사용자를 객체를 따로 구분 , 익명 사용자는 세션에 사용하지 않겠다. 인증 받지 않은 상태를 그대로 유지함. 인증 사용자도, 익명 사용자도 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();
}
익명 사용자도 이름을 변경 가능, 권한에 대해서도 변경 가능
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();
}
<인증 되지 않은 사용자도 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 생성된다.
}
}