서론
오늘은 프로젝트에서 자주 사용되는 Spring Security에 대해서 알아보도록 하자
Spring Security란 / 특징
- Spring Security는 강력하고 고도로 사용자 정의 가능한 인증 및 액세스 제어 프레임워크입니다.
Spring 기반 애플리케이션을 보호하기 위한 사실상의 표준입니다. - Spring Security는 Java 애플리케이션에 인증과 권한 부여를 모두 제공하는 데 중점을 둔 프레임워크입니다.
- 인증 및 권한 부여에 대한 포괄적이고 확장 가능한 지원
- 세션 고정, 클릭재킹, 크로스 사이트 요청 위조 등과 같은 공격으로부터 보호
- 서블릿 API 통합
스프링 시큐리티를 사용하면 인증 관련 로직을 필터를 통해 간단하게 추가할 수 있으며,
필터를 사용하기 때문에, 가장 앞단에서 인증 요청을 걸러줄 수 있으며,
로직 내에서 인증 관련 처리를 따로 해주지 않아도 되기 때문에,
이와 관련된 코드를 서비스마다 직접 관리해주지 않아도 된다!. (일종의 AOP?)
Spring Security 처리 과정
AuthenticationFilter
- HTTP Request가 들어오면 해당 필터는 요청을 가로채 UsernamePasswordAuthenticationToken을 생성한다.
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.security.authentication;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 620L;
private final Object principal;
private Object credentials;
//인증되지 않은 토큰 생성
public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super((Collection)null);
this.principal = principal;
this.credentials = credentials;
this.setAuthenticated(false);
}
//인증된 토큰 생성
public UsernamePasswordAuthenticationToken
(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
//인증되지 않은 토큰 생성
public static UsernamePasswordAuthenticationToken unauthenticated
(Object principal, Object credentials) {
return new UsernamePasswordAuthenticationToken(principal, credentials);
}
//인증된 토큰 생성
public static UsernamePasswordAuthenticationToken authenticated
(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
return new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
}
//...
}
해당 클래스 내부 코드를 통해 알 수 있듯
사용자의 principal, credentials를 통해 인증된 토큰을 생성하고, 이에 대한 권한을 부여한다.
AuthenticationManager (구현체 ProviderManager)
- AuthenticationManager를 상속한 PrividerManager에게 UsernamePasswordToken을 전달한다.
AuthenticationProvider(s)
- 등록된 AuthenticationProvider들을 조회하여 인증을 요구한다.
해당 코드를 보면 알 수 있듯 Providers를 iterator를 통해 하나씩 꺼내 인증되는지 확인한다.
UserDetailsService & UserDetails
UserDetailsService의 loadUserByUsername()메서드를 통해 유저 정보를 찾아
UserDetails 객체를 만들고, AuthenticationProvider들이 이를 통해 사용자 정보를 비교한다.
최종적으로 인증이 완료되면 인증된 Authentication 객체를 반환한다!.
주의사항
만약 formLogin(AbstractHttpConfigurer::disable)를 통해 기본 시큐리티 로그인을 사용하지 않는다면
UserDetailsService, UserDetails는 사용하지 않게 되며,
토큰 기반 필터를 따로 만들었다면, 해당 토큰에서 이에 관한 처리를 따로 해주어야 한다!.
결론
시큐리티를 공부하며, 동작 방식을 알아볼 수 있어서 신기하고 재미있었다!.
디버깅을 통해 어떻게 동작하는지 알아보았는데,
기본 로그인 폼을 사용하지 않으면, UserDetailsService등이 사용되지 않는 것을 알아내는데 오래 걸렸지만,
직접 확인해보며 공부할 수 있어서 재미있었다!.
바로 다음에는 토큰 기반의 로그인 처리 및 관리 과정을 알아보도록 해야겠다!.
'프로그래밍 > Spring' 카테고리의 다른 글
[Spring] Spring Security 토큰 기반 인증 구현 (1) | 2024.07.22 |
---|---|
[Spring] 16. Bean 등록 방법과 의존성 주입 (feat. DI) (0) | 2023.11.07 |
[Spring] 15. 제어의 역전 & 의존성 주입 (IoC & DI) (0) | 2023.11.06 |
[Spring] 14. 자바 빈 & 스프링 컨테이너 (Java Bean & Spring Container) (0) | 2023.09.15 |
[Spring] 13. 프로젝트 설정 (IntelliJ) (0) | 2023.08.25 |