2023. 4. 3. 17:25ㆍSpring
스프링 시큐리티
스프링 기반의 애플리케이션의 보안(인증, 권한, 인가 등)을 담당하는 스프링 하위 프레임워크
장점 :
보안 관련해서 체계적으로 많은 옵션 제공
개발자가 보안 로직을 일일이 작성하지 않아도 됨
기본 용어
접근 주체 : 보호된 리소스에 접근하는 대상
인증 : 보호된 리소스에접근한 대상에 대해 누구인지, 래플리케이션의 작업을 수행해도 되는 주체인지 확인하는 과정
인가 : 해당 리소스에 대해 접근 가능한 권한을 가지고 있는 지 확인하는 과정
권한 : 인가 과정에서 해당 리소스에 대한 제한된 최소한의 권한을 가졌는지 확인
동작
1. HTTP 요청 수신
- 클라이언트로 부터 요청이 오면 인증 및 권한 부여 목적으로 일련의 필터를 거치게 됨
2. UsernamePasswordAuthentication Filter
- 요청이 UsernamePasswordAuthentication Token에 도착하면 해당 클래스의 attempAuthentication(request, response) 메서드가 동작
- attempAuthentication(request, response) :
- request로 부터 username, password를 가져와 사용자 자격 증명을 기반으로한 UsernamePasswordAuthentication Token을 생성
3. AuthenticationManager
- 생성된 토큰을 가지고 AuthenticationManager에게 인증 진행하도록 위임 (AuthenticationManager의 실질적 구현체 : ProviderManager)
4. AuthenticationProvider
- AuthenticationManager로부터 인증 진행을 위임 받은 ProviderManager는 여러 AuthenticationProvider를 순회하면서 UsernamePasswordAuthenticationToken을 처리해줄 Authentication Provider를 탐색
5. UserDetailsService, UserDetails
- DB에서 사용자 인증 정보를 가져올 UserDetailsService 객체에게 사용자 아이디를 넘겨주고, DB에서 인증에 사용할 사용자 정보를 UserDetails라는 객체로 전달 받음
6. AutheticationProvider
- AuthenticationProvider는 UserDetails 객체를 전달 받은 이후 실제 사용자의 입력 정보와 UserDetails 객체를 가지고 인증을 시도
7. SecurityContextHolder
- 인증이 완료되면 사용자 정보를 가진 Authentication 객체를 SecurityContextHolder에 담은 후 AuthenticationSuccessHandle을 실행
Springboot 적용
1. dependency 추가
dependencies {
compile "org.springframework.boot:spring-boot-starter-security"
}
2. 개발시 로그인 폼 해결방법
1) 기본 사용자 계정 등록
// application.yml
spring:
security: # 개발시 login폼 기본 사용자 계정 사용
user:
name: admin
password: password
2) @EnableAuthoConfiguration의 exclude 속성 사용하여 SecurityAutoConfiguration 중지
@SpringBootApplication
@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class})
3. Config
Spring Security 5.7 이상에서 WebSecurityConfigurerAdapter 사용 권장 하지 않음 → SecurityFilterChain Bean 등록 하는 방법 사용
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터 체인에 등록됨
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
// 인증, 인가 서비스가 필요하지 않은 endpoin 적용
@Bean
public WebSecurityCustomizer configure(){
return (web) -> web.ignoring()
.antMatchers(
"/swagger-ui.html"
);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf().disable() // csrf 비활성화
.headers().frameOptions().sameOrigin() // 동일 도메인에서는 X-Frame-Option 활성화
.and()
.authorizeRequests() // 요청에 의한 보안 검사 시작
.antMatchers(
"/api/v1/login"
).permitAll() //antMatchers 에 설정한 리소스의 접근을 인증 절차 없이 허용
.anyRequest().authenticated() // 위에서 설정하지 않은 나머지 부분들은 인증 절차 수행
.and()
.build();
}
}
스프링 시큐리티 설정 방법
리소스의 권한 설정
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests() // 요청에 의한 보안 검사 시작
.antMatchers(
"/api/v1/login"
).permitAll() //antMatchers 에 설정한 리소스의 접근을 인증 절차 없이 허용
.anyRequest().authenticated() // 위에서 설정하지 않은 나머지 부분들은 인증 절차 수행
.and()
.build();
}
antMatchers
특정 리소스에 대해서 권한 설정
antMatchers("/login**", "/web-resources/**", "/actuator/**")
permitAll
antMatchers 설정한 리소스의 접근을 인증 절차 없이 허용
antMatchers("/login**", "/web-resources/**", "/actuator/**").permitAll()
hasAnyRole
antMatchers 설정한 리소스의 접근시 해당 레벨의 권한을 가진 사용자만 접근 허용
antMatchers("/admin/**").hasAnyRole("ADMIN")
anyRequest
나머지 리소스들은 무조건 인증을 완료해야 접근이 가능
anyRequest().authenticated()
커스텀 필터 등록
addFilterBefore
지정된 필터 앞에 커스텀 필터를 추가
UsernamePasswordAuthenticationFilter 보다 먼저 실행됨
public void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new 커스텀 필터("/login-process"),
UsernamePasswordAuthenticationFilter.class);
}
addFilterAfter
지정된 필터 뒤에 커스텀 필터를 추가
UsernamePasswordAuthenticationFilter 이후에 실행됨
public void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(new 커스텀 필터("/login-process"),
UsernamePasswordAuthenticationFilter.class);
}
addFilterAt
지정된 필터의 순서에 커스텀 필터가 추가됨
참고자료
https://docs.spring.io/spring-security/reference/index.html
https://wildeveloperetrain.tistory.com/50
https://kimchanjung.github.io/programming/2020/07/02/spring-security-02/
'Spring' 카테고리의 다른 글
Spring Security Swagger 예외처리 (0) | 2023.04.03 |
---|---|
Spring Swagger (0) | 2023.04.03 |
JPA Mapping (0) | 2023.03.31 |
GenerationType (0) | 2023.03.31 |
Spring_Entity, DTO, VO (0) | 2023.03.22 |