Spring Security
- Spring MVC 기반 애플리케이션의 인증(Authentication)과 인가(Authorization or 권한 부여) 기능을 지원하는 보안 프레임워크
- Spring MVC 기반 애플리케이션에 보안을 적용하기위한 사실상의 표준
Spring Security로 할 수 있는 보안 강화 기능
- 다양한 유형(폼 로그인 인증, 토큰 기반 인증, OAuth 2 기반 인증, LDAP 인증 등)의 사용자 인증 기능 적용
- 애플리케이션 사용자의 역할(Role)에 따른 권한 레벨 적용
- 애플리케이션에 제공하는 리소스에 대한 접근 제어
- 민감한 정보에 대한 데이터 암호화
- SSL 적용
- 일반적으로 잘 알려진 웹 보안 공격 차단
- 외에 SSO, 클라이언트 인증서 기반 인증, 메서드 보안, 접근 제어 목록(Access Control List) 같은 보안을 위한 대부분의 기능을 지원한다.
Spring Security에서 사용하는 용어 정리
- Principal(주체)
- Spring Security에서 사용되는
Principal
은 애플리케이션에서 작업을 수행할 수 있는 사용자, 디바이스 또는 시스템 등이 될 수 있으며, 일반적으로 인증 프로세스가 성공적으로 수행된 사용자의 계정 정보를 의미한다.
Principal과 User
Principal은 User보다 더 구체적인 정보를 의미한다.
일반적으로 Spring Security에서 인증을 시도하는 주체는 User라고 부른다.
Principal은 User보다 더욱 더 구체적인 정보를 의미하며, 일반적으로 Spring Security에서 Username을 의미한다.
- Authentication(인증)
Authentication
은 애플리케이션을 사용하는 사용자가 본인이 맞다고 증명하는 절차를 의미한다.
Authentication
을 정상적으로 수행하기 위해서는 사용자를 식별하기 위한 정보가 필요한데 이를 Credential(신원 증명 정보)
라고 함.
- 현실속 예시) 신분증, 패스워드
- Authoriztioin(인가 또는 권한 부여)
Authorizion
은 Authentication(인증)
이 정상적으로 수행된 사용자에게 하나 이상의 권한(authority)을 부여하여 특정 애플리케이션의 특정 리소스에 접근할 수 있게 허가하는 과정을 의미.
Authorization
은 반드시 Authentication(인증)
과정 이후 수행되어야 하며 권한은 일반적으로 역할(Role) 형태로 부여됨.
- Access Control(접근 제어)
Access Control
은 사용자가 애플리케이션의 리소스에 접근하는 행위를 제어하는 것을 의미함.
Spring Security 적용 의존 라이브러리
implementation 'org.springframework.boot:spring-boot-starter-security'
build.gradle
에 위의 의존 라이브러리를 추가하고, 애플리케이션을 실행시키면,
Spring Security에 의해서 기본 UI가 제공된다.
Username 은 user
를,
Password는 아래 그림과 같이 애플리케이션 실행시에 로그에서 확인 가능하다.
Spring Securtiry의 관리 정보
- Spring Security에서
SimpleGrantedAuthority
를 사용해서 Role 베이스 형태의 권한을 지정할 때, 'Roll_'+권한명
형태로 지정해 줘야한다.
- 위와 같이 이뤄지지 않을 경우, 적절한 권한 매핑이 이루어지지 않는다.
PasswordEncoder
를 이용해서 등록한 User의 패스워드를 암호화해주어야 한다.
- 패스워드를 암호화하지 않는다면, User의 등록은 되지만, 로그인 인증 시, 아래의 에러를 만나게 되므로, User의 패스워드는 반드시 암호화 해야 한다.
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null”
- Spring Securtity에서 관리하는 User 정보를
UserDetails
로 관리한다.
Custom UserDetailsService를 사용하는 방법
Spring Security에서는 User의 인증 정보를 테이블에 저장하고, 테이블에 저장된 인증 정보를 이용해 인증 프로세스를 진행할 수 있는 몇 가지 방법이 존재하는데 그 중 한 가지 방법이 UserDetailsService를 이용하는 것이다.
- Spring Security에서 Clickjackint 공격을 막기 위해 기본적으로 frameOptions() 기능이 활성화 되어있다.
- Default 값은
DENY
이다.
- 즉, HTML 태그를 이용한 페이지 렌더링을 허용하지 않겠다는 의미
패스워드의 암호화
- User로 사용하는 클래스의 password로 사용하는 필드를 얻어와서, PasswordEncoder의 객체로 encode를 한다.
- 그리고 encode된 password를 Setter로 바꿔서, 해당 클래스의 인스턴스의 password로 사용하는 필드에 넣는다.
패스워드를 데이터베이스에 저장할 때, 암호화하지 않고 평문 그대로 저장하는 경우가 있다. 암호화를 반드시 해서 저장되어야 한다.
그리고, 패스워드는 암호화 된 상태에서 복호화 할 이유가 없기 때문에, 단방향 암호화 방식으로 암호화 되어야한다.
UserDetailsService
Spring Security에서 제공하는 컴포넌트 중 하나로서, User 정보를 로드(load)하는 핵심 인터페이스다.
- 로드(load)의 의미 : 인증에 필요한 User 정보를 어딘가에서 가지고 온다는 의미이다.
- 위의 문장에서
어딘가
는 메모리가 될 수도 있고, DB 등의 영구 저장소가 될 수도 있다. 여하튼 가지고 온다는 의미이다.
UserDetails
- UserDetailsService에 의해서 로드(load)되어 인증을 위해 사용되는 핵심 User정보를 표현하는 인터페이스이다.
- UserDetails 인터페이스의 구현체는 Spring Security에서 보안 정보 제공을 목적으로 직접 사용되지는 않고,
Authentication
객체로 캡슐화 되어 제공된다.
특정 이메일 주소에 관리자 권한부여
application.yml 파일에
mail:
address:
admin: admin@gmail.com
추가하면 된다.
크리덴셜(Credential)
- 해당 *사용자를 증명하기 위한 구체적인 수단을 의미한다.
- 일반적으로는 사용자의 패스워드가 크리덴셜에 해당함.
Spring Securtity에서의 필터
DelegatingFilterProxy
- Bean으로 등록된 Spring Security의 필터를 사용하는 시작점.
- 딱히 보안과 관련된 작업을 처리하지는 않는다.
- 서블릿 컨테이너 영역의 필터와 ApplicationContext에 Bean으로 등록된 필터들을 연결해주는 브릿지 역할을 한다.
FilterChainProxy
- FilterChain은 Spring Securtity에서 보안을 위한 작업을 처리하는 필터의 모음이다.
- Spring Security의 Filter를 사용하기 위한 진입점이다.
커밋 O