Spring Security란?
Spring 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 Spring 하위 프레임워크
개발자가 보안 관련 로직을 작성하는 것을 대폭 줄여주는 장점을 갖고 있다.
Spring Security 구성요소
1. HTTP 요청 수신, Authentication Filter 통과
Spring Security는 여러개의 연결된 필터(필터체인)를 갖고 있는데, Request는 인증, 인가를 허락받기 위해 이 필터체인을 통과하게 되고, 해당 요청과 관련된 인증 필터를 찾을 때까지 통과한다.
ex) HTTP Basic 인증 요청은 BasicAuthenticationFilter에 도달할 때까지 필터 체인을 통과한다.
ex) HTTP Digest 인증 요청은 DigestAuthenticationFilter에 도달할 때까지 필터 체인을 통과한다.
ex) 로그인 form submit 요청은 UsernamePasswordAuthenticationFilter에 도달할 때까지 필터 체인을 통과한다.
ex) X509 인증 요청은 X509AuthenticationFilter 등에 도달할 때까지 필터 체인을 통과한다.
필터체인 중 인증을 담당하는 필터를 인증 필터라고 한다.
2. 사용자 자격 증명을 기반으로 AuthenticationToken 생성
Request에 담긴 토큰을 해석하여 validation을 진행하고, 이상이 없다면 Authentication 의 구현체인 UsernamePasswordAuthenticationToken 에 UserDetails(사용자 자격 증명)을 담습니다.
3. AuthenticationManager은 등록된 Provider에게 인증을 명령
AuthenticationManager는 등록된 모든 AuthenticationProvider들에게 authenticate 하도록 명령합니다.
4. AuthenticationProvider는 인증 로직을 처리
우선 AuthenticationProvider는 Security 설정에서 AuthenticationManager에 등록되어야 합니다. Provider의 인증 로직은 개발자가 커스터마이징할 수 있습니다.
5. 인증이 완료된 Authentication의 등록
인증이 모두 완료되면, Authentication에 Principal, Credential, Authority 정보를 담습니다.
- Principal : 유저 정보 또는 ID
- Credential : Password
- Authority : 권한(Role)
마지막으로, Authentication이 SecurityContext에 저장됩니다.
(SecurityContext는 모든 로직을 통과한 인증된 사용자의 정보(인증 개체)를 저장하는 공간)
Spring Security 설정
http
.csrf().disable()
.formLogin().disable()
.logout().logoutUrl("/logout").permitAll()
.deleteCookies("accessToken")
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.and()
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/**").permitAll()
.and()
.addFilterBefore(new JwtAuthenticationFilter(authenticationManager(), provider), UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(entryPoint)
.accessDeniedHandler(accessDeniedHandler);
1. csrf.disable
- CSRF(Cross-Site Request Forgery)란 사이트간 위조 요청을 말합니다. Spring Security에서 CSRF 설정 한다는 것은 HTML에서 어떤 요청을 할 때 CSRF 토큰이 포함해야 서버에서 요청을 받도록 하는 것을 말합니다.
- Documentation에 따르면 CSRF 방지 설정은 브라우저를 통해 사용자가 요청을 할 때 사용
- 필요하지 않을 때는 세션 기반 인증이 아닌 stateless한 인증을 사용할 때 설정하지 않음
- 이유는 서버에서 인증 정보를 보관하지 않고, 사용자가 권한이 필요한 요청을 할 때마다 필요한 인증 정보(JWT토큰)를 포함시키기 때문에 부가적으로 csrf 로직을 작성하지 않음
2. formlogin
- Spring Security에서 기본적으로 제공하는 form 태그 기반의 로그인에 대한 속성
- 기본적으로 제공하는 form태그 관련 로그인을 사용하지 않도록 설정
3. logout
- 로그아웃과 관련된 설정
- “/logout” 경로로 로그아웃을 진행하도록 설정, 성공 시 “/” 경로로 이동
- 모든 사용자가 접근 가능하고 로그아웃 시 accessToken을 담은 쿠키를 삭제하도록 설정
4. invalidateHttpSession
- 로그아웃 시 세션 삭제
5. headers().frameOptions().disable()
- h2-console 사용을 위함
6. authorizeRequests
- 특정 경로에 특정 사용자 권한만 접근하도록 설정할 때 사용
7. addFilterBefore
- 필터 추가 시 사용
- JWT 토큰 인증에 필요한 필터를 추가
8. sessionManagement().sessionCreationPolicy
- 스프링 시큐리티가 세션을 생성하지 않고 기존 세션을 사용하지도 않음
- 세션 기반 인증을 사용하지 않고 JWT 토큰 인증 방식을 사용하니 필요 없음
9. exceptionHandling
- authenticationEntryPoint
- 인증 실패 시 처리할 Handler
- accessDeniedHandler
- 인가 실패 시 처리할 Handler
참고자료
https://doozi0316.tistory.com/entry/Spring-Security-Spring-Security의-개념과-동작-과정
'# Back-End > Spring' 카테고리의 다른 글
@Vaild를 이용한 Validation 검증 (0) | 2022.01.24 |
---|---|
@Secured, @PreAuthorized를 이용한 메소드 수준의 권한 적용 (0) | 2022.01.23 |
Role Enum 클래스를 이용한 인가 (0) | 2022.01.23 |
JWT란? (0) | 2022.01.23 |
인증 방식 비교(서버 기반 인증, 토큰 기반 인증) (0) | 2022.01.23 |
Filter, Interceptor, AOP (필터, 인터셉터, AOP) (0) | 2022.01.23 |
[Test] Spring Layer별 테스트 작성 (1) | 2022.01.23 |