
Web 기반 Application에 보안적인 제한을 추가하기 위해 사용하는 Security Framework 중에 하나이다.
Spring Security의 주된 목표는 rest api endpoint, mvc url, 정적 리소스와 같은 리소스들에 접근하려는 요청의 인증을 책임지는것이다.
Spring Security 는 Spring 생태계와 호환성이 높고 커스텀이 매우 쉽다
(Spring Security 같은 경우엔 책 한권을 쓸 수 있을정도로 굉장히 딥하다고 한다.)
스프링 시큐리티를 사용하면 따로 로그인에 관한 디테일한 인터페이스를 내가 직접 구현하지 않아도 스프링 시큐리티 설정 하나로 깔끔하게 인증과 인가를 구현할 수 있다.

이렇게 내가 따로 폼을 작성하지 않아도 로그인 뷰가 알아서 구현이 된다. (물론 로그인은 따로 entity 와 연동을 해줘야한다.)

Spring Security 를 한 문장으로 소개한다면
스프링 생태계에서 인증과 인가라는 개념을 최대한 쉽고 유연하게 구현할 수 있도록 만들어진 Framework 라고 소개할 수 있다.
그만큼 인증과 인가는 Spring Security 의 개념들 중에 하나에 그치는게 아니라 Spring Security가 궁극적으로 이루고자 하는 목표이다.
인증은 사용자가 누구인지 확인하는 절차이다 .
단순히 말해 "당신은 누구인가?" 에 대한 답을 말하는것이다.
단적인 예로 로그인을 말한다.
위에 대한 질문의 답으로 나는 나의 아이디와 비밀번호를 답으로 말하는것이다.
위의 사진을 예로 든다면 인증은 내가 누군지 전달을 하고, 나 라는 객체가 등록이 되어있다면 나는 '나'인증을 받게 된다.
인가는 인증 이후에 리소스에 대한 권한 통제를 의미한다.
클라이언트가 요청한 작업이 허가된 작업인지 확인하는 절차이다.
단순히 말해 인가는 당신은 무엇을 할 수 있습니까? 라는 것이다.
인가에 따라서 내가 인증을 받은 뒤에 할 수 있는 행동이 제한된다.

해당 그림과 마찬가지로 SecurityContextHolder -> SecurityContext -> Authentication -> Principal & GrantAuthority
라고 생각하면 된다. (Principal & GrantAuthority 이 제일 안에 속해있다.)
SecurityContext 를 제공하는 static 메소드 (getContext)를 지원한다.
SecurityContext는 Authentication (인증) 을 보관하는 역할을 하며, SecurityContext를 통해 Authentication 객체를 꺼내올 수 있다.
WebMVC 기반으로 프로젝트를 만든다는 가정하에 대부분의 경우에는 요청 1개에 스레드 1개가 생성되지만, ThreadLocal 을 사용하면 Thread마다 고유한 공간을 만들수가 있고, 그곳에 SecurityContext를 저장할 수 있다.
MODE_THREADLOCAL
ThreadLocalSecurityContextHolderStrategy 를 사용한다.
ThreadLocal 을 사용하여 같은 Thread 안에서 SecurityContext를 공유한다.
-> 가장 기본 설정 모드이다.
MODE_INHERITABLETHREADLOCAL
InheritableThreadLocalSecurityContextHolderStrategy 를 사용한다.
InheritableThreadLocal 을 사용하여 자식 Thread까지도 SecurityContext를 공유한다.
MODE_GLOBAL
GlobalSecurityContextHolderStrategy를 사용한다.
Global로 설정되어 애플리케이션 전체에서 SecurityContext 를 공유한다.
SpringSecurity 를 이용하다보면, 암호화된 비밀번호를 입력받지 않으면 오류가 발생한다. (내가 겪어봄)
그래서 회원가입을 할때, 로그인화면에서 비밀번호를 입력할때 SpringSecurity 를 활용하여 로그인을 하려면 암호화를 시켜주어야 한다.
이를 PasswordEncoder 가 해결해준다.
PasswordEncoder 는 비밀번호를 입력받으면 값을 암호화해서 저장해주고,
로그인할때 입력받은 Password 와 회원가입 할떄의 Password를 비교해주는 기능을 지원한다.
이 두가지를 만족하기 위해서는 해시 함수라는 알고리즘 방식을 이용한다.
이것을 사용하면 위의 문제들을 모두 해결해준다.
패스워드 인코더는 다양한 암호화 전략이 있다.
해당 전략은 기존의 단순 문자열을 암호화하지 않고 평문으로 사용한다.
비밀번호 앞에 단순히 {noop} 를 붙여서 사용한다. 비밀번호가 그대로 노출되기 때문에 추천되지 않는다.
Bcrypt 해시 함수를 사용한 인코더이다. 패스워드 저장을 목적으로 설계되었다.
비밀번호를 무작위로 여러번 시도하여 맞추는 해킹을 방지하기 위해 암호를 확인할 때 의도적으로 느리게 설정되어있다.
Pbkdf2는 NIST (미국표준기술연구소)에 의해서 승인된 알고리즘이고, 미국 정부 시스템에서도 사용된다.
보안에 아주 민감한 경우에 사용할 수 있다.
다음 글에서 직접 활용해보자.