// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
'Spring Security' 활성화
@SpringBootApplication
public class SpringAuthApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAuthApplication.class, args);
}
}
'Spring Security' 설정
package com.sparta.springauth.config;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity // Spring Security 지원을 가능하게 함
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// CSRF 설정
http.csrf((csrf) -> csrf.disable());
http.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() // resources 접근 허용 설정
.anyRequest().authenticated() // 그 외 모든 요청 인증처리
);
// 로그인 사용
http.formLogin(Customizer.withDefaults());
return http.build();
}
}
http.csrf((csrf) -> csrf.disable());
http.formLogin(Customizer.withDefaults());
Spring Security - Filter Chain
- Spring에서 모든 호출은 DispatcherServlet을 통과하게 되고
- 이후에 각 요청을 담당하는 Controller로 분배됨
- 이 때, 각 요청에 대해서 공통적으로 처리해야할 필요가 있을 때 DispatcherServlet 이전의 단계가 필요
- 이것이 Filter !
- Spring Security도 인증 및 인가를 처리하기 위해 Filter 사용
- Spring Security는 FilterChainProxy를 통해서 상세로직 구현
Form Login 기반은 인증
- Form Login 기반 인증은 인증이 필요한 URL 요청이 들어왔을 때 인증이 되지 않았다면 로그인 페이지를 반환하는 형태
UsernamePasswordAuthenticationFilter
- UsernamePasswordAuthenticationFilter는 Spring Security의 필터인 AbstractAuthenticationProcessingFilter를 상속한 필터
- AbstractAuthenticationProcessingFilter : 웹 기반 인증요청에서 사용되는 컴포넌트로 POST 폼 데이터를 포함하는 요청을 처리
- 기본적으로 Form Login 기반을 사용할 때 username과 password 확인하여 인증
- 인증 과정
1. 사용자가 username과 password를 제출하면 UsernamePasswordAuthenticationFilter는 인증된 사용자의 정보가 담기는 인증 객체인 Authentication의 종류 중 하나인 UsernamePasswordAuthenticationToken을 만들어 AuthenticationManager에게 넘겨 인증을 시도함
2. 실패하면 SecurityContextHolder를 비움
3. 성공하면 SecurityContextHolder에 Authentication 세팅SecurityContextHolder
- 인증이 완료된 사용자의 상세 정보(Authentication) 저장
- SecurityContextHolder로 접근 가능
Authentication
- 현재 인증된 사용자
- SecurityContext에서 가져올 수 있음
- principal : 사용자를 식별함
- Username/Password 방식으로 인증할 때 일반적으로 UserDetails 인스턴스
- credentials
- 주로 비밀번호
- 대부분 사용자 인증에 사용한 후 비움
- authorities
- 사용자에게 부여한 권한을 GrantedAuthority로 추상화하여 사용
UsernamePasswordAuthenticationToken
- Authentication을 implements한 AbstractAuthenticationToken의 하위 클래스
- 인증객체를 만드는데 사용됨
UserDetailsService
- username/password 인증방식을 사용할 때 사용자를 조회하고 검증한 후 UserDetails를 반환
- Custom하여 Bean으로 등록 후 사용 가능
UserDetails
- UsernamePasswordAuthenticationToken 타입의 Authentication를 만들 때 사용됨
- 해당 인증개체는 SecurityContextHolder에 세팅됨
- Custom하여 사용 가능