Spring Security
1. 인증(Authentication) 과 인가(Authorization)
- 인증은 사용자가 자신을 증명하는 것
- 인가는 사용자를 인가하는 일종의 허가를 해주는 과정
- 인증 후 인가 절차를 거침
- Security 설정하는 SecurityConfig에 WebSecurityConfigurerAdapter 클래스를 상속 받아 처리했지만 현재 deprecated
- SecurityFilterChain 빈 등록 방식으로 변경
- 인증 > 테스트 user 생성 시 AuthenticationManagerBuilder x
@Bean
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("kmj")
.password("$2a$10$ZDFtW4pl8g.X93NgxbM27.ehqj9MRnYjr.8hZnIZsmZuNMCWuKafS")
.roles("USER");
}
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
UserDetails user = User.builder().username("kmj")
.password("$2a$10$ZDFtW4pl8g.X93NgxbM27.ehqj9MRnYjr.8hZnIZsmZuNMCWuKafS")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
3. 작동방식
- 사용자가 원하는 url 입력
- 스프링 시큐리티에서는 인증/인가가 필요하다고 판단(필터에서) 후 사용자가 인증하도록 로그인 화면을 보여준다.
- 정보 전달 후 AuthenticationManger가 적절한 AuthenticationProvider를 찾아 인증을 시도한다.
- AuthenticationProvider의 실제 동작은 UserDetailService를 구현한 객체로 처리
- 올바른 사용자라고 인증될 시 사용자의 정보를 Authentication 타입으로 전달
'인증'
- 전달된 객체로 사용자가 적절한 권한이 있는지 확인하는
'인가'
과정을 거침
- 문제가 없으면 요청한 url에 해당하는 화면을 반환한다.
패스워드 인코딩
* PasswordEncoder
ㆍ BCryptPasswordEncoder 클래스
: bcrypt 해시 함수를 이용해서 암호화
: 암호화된 패스워드는 다시 복호화가 불가하며 매번 암호화된 값도 다름(길이는 동일)
@EnableWebSecurity
@Configuration
@Log4j2
public class SecurityConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
SecurityFilterChain
스프링 시큐리티의 필터()들이 묶여있는 필터체인이다.
애플리케이션에서 여러개의 SecurityFilterChain이 독립적으로 존재할 수 있으며
FilterChainProxy를 통해 요청에 매칭된다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/sample/all").permitAll()
.antMatchers("/sample/ex*").permitAll()
.antMatchers("/sample/member").hasRole("USER");
http.formLogin();
http.csrf().disable();
http.logout();
return http.build();
}
CSRF 설정
ㆍ CSRF
: 스프링 시큐리티는 기본적으로 CSRF(Cross Site Request Forgery) 공격을 방어하기 위해
GET 방식을 제외한 모든 요청 방식 등에 포함시켜야 정상적인 동작이 가능함
ㆍ CSRF 토큰 비활성화
: REST 방식 등에서 매번 CSRF 토큰 값을 알아내야 하는 불편함이 있어 토큰 비활성화 설정
http.csrf().disable();