2022. 6. 21. 16:48ㆍWeb/Spring
Session 1 스프링 시큐리티 기본 이해
목적 : usernameAuthenticationFilter, LogoutFilter, RememberMeAuthenticationFilter, AnonymousFilterAuthenticationFilter, SessionManagementFilter, ConcurrentSessionFilter 단어 이해
Spring Security는 기본적으로 authentication, authorization 과 protection을 지원한다.
- Authentication : 특정 리소스에 접근하려고 하는 사람이 누구인지 확인한다. 가장 쉬운 방법은 username과 password (우리가 흔히 아는 아이디와 로그인 같음)를 통해서이다. 이를 위해 Spring에서는 PasswordEncoder를 사용하는데 이는 비밀번호를 안전하게 저장될 수 있도록 한다.
- Authorization : 특정 리소스에 접근할 수 있는 권한을 정해준다. defense in depth를 활용하여 request based와 method authrization을 허용한다.
- Protection
- CSRF(Cross Site Request Forgery 사이트 간 요청 위조 : 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격) 방지
- Security HTTP Response Headers 제공
- HTTP Request : HTTP 커넥션을 관리하지는 않지만 HTTPS 사용을 위한 여러가지 기능을 제공한다. (Redirect to HTTPS, Strict Transport Security, Proxy Server Configuration)
아키텍처
Spring Security Servlet은 기본적으로 Servlet의 Filters를 지원하여 Filter의 역할을 볼 수 있다.
- Filter
Client가 애플리케이션에 대한 Request를 보내면 컨테이너가 FilterChain을 생성하는데 위 그림과 같이 Filter와 Servlet을 포함하고 있다. 1개 이상의 Filter가 사용된다.
(여기서 Servlet은 HttpServlet Request와 HttpServletResponse를 다룬다.)
- FilterChainProxy
Servlet 자원이 포함되어 있는 곳. 고정된 bean name으로 SecurityFilterChain을 통해 많은 Filter 인스턴스로 위임할 수 있다. DelegatingFilterProxy로 래핑된다. (보통 고정된 이름으로 SpringSecurityFilterChain이라 불린다.)
DelegationFilterProxy -> FilterChainProxy -> List 구조로 된다.
FilterChainProxy 아래에 여러 Filter Chain이 존재할 수 있다.
(Type Filter는 자동적으로 컨테이너에 등록되기 때문에 만약 Custom Filter를 만드려고 한다면 @Bean 형태로 만들어야 함.)
이렇게 AuthenticationToken은 AuthenticationManager로 전달이 된다. AuthenticationManager는 실제로 인터페이스로 authenticate method를 ProviderManager에 의해 implement 되었다. 이렇게 Manager를 통해 성공과 실패의 경우로 나뉘게 된다.
1. username과 password를 제출했으면 usernamePasswordAuthenticationFilter가 HttpServletRequest로부터 가져온 ㅕusername과 password를 갖고 Token을 만든다.
2. usernamePasswordAuthenticationToekn은 AuthenticationMananger에서 인증 과정을 거친다.
3. 만약 Authentication이 실패했다면 SecurityContextHolder를 지우고, AuthenticationFailureHandler를 실행한다.
4. Authentication이 성공 했다면 SessionAuthenticationStrategy에게 새로운 로그인이 있음을 알린다. Authentication은 SecurityContextHolder에 있다. SuccessEvent가 발생하고, AuthenticationSuccessHandler가 실행된다.
- UsernamePasswordAuthenticationFilter : Form based Authentication. Form Login 인증을 진행할 때 아이디, 패스워드 데이터를 파싱하여 인증 요청을 위임하는 필터. form에서 아이디와 비밀번호가 넘어왔으면 UsernamePasswordAuthenticationToken의 인스턴스를 생성한다. 이 Token은 Authentication을 사용하기 위해 AuthenticationProvider를 거친다.
- Remember Me
스프링에서는 기본적으로 remember-me 라는 기능을 제공하고 있다. 기본적으로 cookie 정보로 동작한다.
우리가 로그인을 할 때 로그인 유지라는 checkbox를 본적이 있을 것이다. 이를 체크 하고 로그인을 하면 창을 닫더라도 로그인이 되는데 이는 Spring에서 Remember me 기능으로 가능하다. remeber me 쿠키 생성하고 http header에 이를 담아 request 하고 서버에서는 이를 확인하여 Token 기반 Authentication으로 로그인을 승인해준다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/register")
.permitAll()
.antMatchers("/account/**").hasAuthority("USER")
.and()
.rememberMe().userDetailsService(this.userDetailsService)
....
}
rememberMe().userDetailsService(this.userDetailsService)를 활용하면 remember me service를 사용할 수 있고 authentication token을 만들고 remember me cookie를 만들어서 브라우저로 다시 보낸다.
- RememberMeAuthenticationFilter : Authentication 객체가 SecurityContext에 있는지 확인하며 remember-me authentication token을 저장한다.
참고 자료
https://stackoverflow.com/questions/41480102/how-spring-security-filter-chain-works
https://www.baeldung.com/spring-security-extra-login-fields
https://docs.spring.io/spring-security/reference/index.html
https://spring.io/guides/topicals/spring-security-architecture
https://www.javadevjournal.com/spring-security/spring-security-remember-me/
'Web > Spring' 카테고리의 다른 글
[Spring] QueryDSL 오류 - org.springframework.dao.InvalidDataAccessApiUsageException: No sources given (0) | 2022.06.23 |
---|---|
[Spring] Spring Security - 기본 이해 (2) (0) | 2022.06.22 |
[JPA] QueryDSL 사용하기 - 환경설정 (1) (0) | 2022.06.20 |
[Spring] 생성자 주입 vs 필드 주입 - Spring 특성 (2) (0) | 2022.05.29 |
[Spring] 생성자 주입 vs 필드 주입 - Spring 특성 (1) (0) | 2022.05.27 |