Spring Security를 이용하기 전에, 인증과 보안의 기초가되는 개념들의 Flow를 중심으로 먼저 정리하려한다.
HTTPS (Hyper Text Transfer Protocol Secure Socket layer)는 HTTP요청을 SSL 혹은 TLS 알고리즘을 이용해서 HTTP통신을 하는 과정에서 데이터를 암호화하여 전송하는 방법이다.
HTTPS는 다음의 목적으로 사용한다.
1) 암호화
제 3자가 서버와 클라이언트가 주고받는 정보를 탈취할 수 없도록 하는 것이다.
이를 위해 서버와 클라는 서로가 합의한 방법으로 데이터를 암호화하여 주고받는다. 따라서 중간에 제 3자에게 데이터가 탈취당해도 그 내용을 알아볼 수가 없다.
(데이터를 암호화하여 전송하는 HTTPS를 사용한다면 비밀번호와 같은 중요한 데이터가 유출될 가능성이 HTTP보다 현저히 적어진다.)
(HTTP는 요청 및 응답이 탈취되면 데이터의 내용을 제 3자가 그대로 확인할 수 있다.)
HTTPS에서는 클라와 서버가 데이터를 암호화하여 주고받기 위해 비대칭키 방식과 대칭키 방식을 혼용해서 사용한다.
대칭키 방식 : 양쪽이 공통의 비밀키를 공유하여 데이터를 암호화 및 복호화하는 것
비대칭키 방식 : 각각 공개키와 비밀키(개인키)를 가지고 상대가 나의 공개키로 암호화한 데이터를 개인이 가진 비밀키로 복호화하는 것
클라와 서버가 데이터를 주고받을 때는 대칭키를 사용한다. (비대칭키 알고리즘이 대칭키보다 복잡하기 때문에 대칭 키를 사용해서 데이터를 암호화 및 복호화하는 것이 훨씬 컴퓨터에 부담을 덜 주기 때문)
그리고 이렇게 대칭키를 주고받을 때 비대칭키 방식으로 주고받도록한다.
2) 인증서
HTTPS의 또 다른 특징 중 하나는 브라우저가 서버의 응답과 함께 전달된 인증서를 확인할 수 있다는 점이다. 인증서는 서버의 신원을 보증해서 접속한 사이트 (Ex_네이버)가 가짜가 아님을 보장해주는 역할을 한다.
이렇게 보증할 수 있는 제 3자를 CA (Certificate Authority)라고 부른다. (인증서를 발급해주는 공인된 기관들을 말함)
CA들은 서버의 공개키와 정보를 CA의 비밀키로 암호화해서 인증서를 발급한다.
서버가 클라에게 CA에서 발급받은 인증서를 전달하면 클라는 OS또는 브라우저에 미리 내장되어있던 CA리스트를 통해 브라우저에서 인증된 CA에서 발급받은 인증서인지 먼저 확인한다.
만약 인증된 CA에서 발급한 인증서가 아니면 경고창이 뜨면서 서버와 연결이 안전하지 않다고 알린다.
그후 인증서가 확인 되었으면, 브라우저에 제공된 해당 CA기관의 공개키로 서버 인증서를 복호화한다. 이렇게 서명을 복호화해서 얻은 공개키로 클라는 서버를 믿을만한 대상인지 신뢰할 수 있다. (인증서가 위조되었다면 CA의 공개키로 서버의 인증서를 복호화할 수 없으니까)
따라서 브라우저는 인증서의 도메인과 데이터를 제공하는 서버의 도메인을 비교할 수 있으므로 '중간자 공격'을 감지해서 보안 위협으로부터 사용자 및 사용자의 데이터를 보호할 수 있다.
또한 경고창을 직접 보여줌으로 브라우저들은 인증된 CA가 발급한 인증서를 이용하여 데이터를 제공하는 안전한 서버를 사용자가 사용하도록 유도한다.
이렇게 서버와 클라간의 CA를 통해 서버를 인증하는 과정과 데이터를 암호화하는 과정을 아우른 프로토콜을 TLS 또는 SSL이라고한다.
(SSL이 표준화되며 바뀐이름이 TLS이다. 그니까 사실한 동일한 규약을 뜻한다는걸 잊지말쟈..)
1) Spring Initializr에서 기본 웹 서버 프로젝트를 생성한다.
2) 설치
mkcert를 이용해서 로컬환경 내에서 신뢰할 수 있는 PKCS12형식의 인증서를 만들 수 있다.
(mkcert를 이용해 생성한 인증서는 로컬 환경에서만 인증 가능한 사설 인증서기 때문에 배포 환경에서는 사용할 수 없다)
나는 윈도우와 맥을 둘 다 사용해서 아래와 같이 구분해서 설치했다.
$ cd {프로젝트 저장 위치}
-------------------------
$ sudo apt install libnss3-tools
$ wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64
$ chmod +x mkcert
$ sudo cp mkcert /usr/local/bin/
$ brew install mkcert
# firefox를 사용할 경우 필요에 따라 설치
$ brew install nss
3) 인증서 생성
아래 명령어를 통해 인증된 발급기관으로 추가해야한다.
$ mkcert -install
CA가 생성되고 설치되면 PKCS12 형식 인증서를 생성할 수 있다.
$ mkcert -pkcs12 localhost //PKCS12 인증서를 생성하기 위해
이제 옵션으로 추가한 localhost에서 사용할 수 있는 인증서 완성~!
이 커맨드를 입력한 위치에 localhost.p12파일이 생성된 것을 확인할 수 있다.
4) HTTPS 서버 작성
Spring Boot를 이용해서 HTTPS서버를 간단하게 작성할 수 있다.
생성된 인증서를 resources 폴더로 이동시키고, application.properties에서 관련 설정을 추가한다.
server.ssl.key-store=classpath:localhost.p12 # -> 인증서 경로를 적습니다.
server.ssl.key-store-type=PKCS12 # -> 인증서 형식을 적습니다.
server.ssl.key-store-password=changeit # -> 인증서 비밀번호를 적습니다.
# 여기서 비밀번호인 changeit은 비밀번호를 설정하지 않았을 때의 기본값입니다.
# 인증서 비밀번호는 인증서를 생성할 때 설정하거나 생성 후 변경해줄 수 있습니다.
이러고 서버를 실행시켜뵤면 HTTPS서버가 작동하는걸 확인할 수 있다.

해싱은 가장 많이 쓰이는 암호화 방식 중 하나이며, 복호화가 가능한 다른 암호화 방식과 달리 해싱은 암호화만 가능하다.
해싱은 해시 함수를 사용해서 암호화를 진행하는데, 해시함수의 특징은 다음과 같다.
항상 같은 길이의 문자열을 리턴한다.
서로 다른 문자열에 동일한 해시 함수를 사용하면 반드시 다른 결과값이 나온다.
동일한 문자열에 동일한 해시 함수를 사용하면 항상 같은 결과값이 나온다.
사용자가 인증에 성공한 상태를 세션이라고 부르며, 서버는 일종의 저장소에 세션을 저장한다. (주로 in-memory 또는 세션 스토어에 저장한다.)
세션이 만들어지면, 각 세션을 구분할 수 있는 세션 아이디도 만들어지는데, 보통 클라에 세션 성공을 증명할 수단으로써 세션 아이디를 전달한다.
이때 웹사이트에서 로그인을 유지하기 위한 수단으로 쿠키를 사용한다. 쿠키에는 서버에서 발급한 세션 아이디를 저장한다.