'Spring Security' 프레임워크는 Spring 서버에 필요한 인증 및 인가를 위해 많은 기능을 제공해준다.
// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
@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();
}
}
🔥 CSRF(사이트 간 요청 위조, Cross-site request forgery)
공격자가 인증된 브라우저에 저장된 쿠키의 세션 정보를 활용하여 웹 서버에 사용자가 의도하지 않은 요청을 전달하는 것
- CSRF 설정이 되어있는 경우, html에서 CSRF 토큰값을 넘겨주어야 요청을 수신 가능하다.
- 쿠키 기반의 취약점을 이용한 공격이기 때문에 REST 방식의 API에서는 disable 가능하다.
- POST 요청마다 처리해 주는 대신 CSRF protection 을 disable 하겠다.
http.csrf((csrf) -> csrf.disable());
Spring Security에서는 default로 로그인 기능을 제공해준다.
// 예시코드
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
context.setAuthentication(authentication); // SecurityContext 에 인증 객체 Authentication 를 저장합니다.
SecurityContextHolder.setContext(context);
// UserDetails
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
UserRoleEnum role = user.getRole();
String authority = role.getAuthority();
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(simpleGrantedAuthority);
return authorities;
}
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
UserDetailsService는 username/password 인증방식을 사용할 때 사용자를 조회하고 검증한 후 UserDetails를 반환한다. Custom하여 Bean으로 등록 후 구현하여 사용 가능하다.
검증된 UserDetails는 UsernamePasswordAuthenticationToken 타입의 Authentication를 만들 때 사용되며 해당 인증객체는 SecurityContextHolder에 세팅된다. 마찬가지로 Custom하여 구현하여 사용가능하다.