인증(Authentication) 전략은 보호된 리소스에 대한 액세스 권한을 부여하기 위해 사용자 또는 시스템의 신원을 확인하는 데 사용되는 방법 또는 기술이다.
인증이 무엇이며 어떻게 작동하는지 알고 애플리케이션에 대한 인증 전략을 선택할 때 더 나은 결정을 내려보자.
- HTTP를 통해 리소스에 접근하기 위한 인증 방법으로, credentials가 요청 헤더로 전달되는 방식이다.
- API에서도 사용할 수 있으며, 이 경우에는 token based Authentication과 유사하다.
- TLS/HTTPS와 사용하지 않으면 누구나 credentials를 디코딩할 수 있기 때문에 안전하지 않다.
클라이언트가 보호된 URL에 접근한다.
서버는 요청이 Authorization
헤더가 올바른 credentials를 가지고 있는지 확인해 응답한다.
WWW-Authenticate: Basic realm="..."
와 같은 응답을 포함하는데, 여기서 realm은 같은 credentials가 필요한 보호된 페이지들의 집합을 말한다. 브라우저는 realm을 통해 유효한 credentials를 캐시해두고 사용할 수 있다. 401 응답을 받으면 브라우저는 응답 헤더에서 WWW-Authenticate
를 확인하고, 화면에 credentials에 대한 경고를 표시한다.
유저는 credentials(username, password, ...)
를 제출한다. 브라우저는 credentials를 base64로 인코딩해서 다음 요청에 보낸다. creadentials는 Authorization
헤더에 담겨 보내진다.
Authorization: Basic ...
2단계로 돌아가서 다시 인증을 수행한다.
- 유저가 유니크한 identifier에 배정된다. identifier는 서버 메모리에 저장된다. 이 identifier를 session이라고 한다.
- 클라이언트는 session id를 모든 요청에 담아 보낸다. 서버는 이것으로 유저를 식별한다.
- stateful한 인증 방법이다.
서버는 계속해서 메모리(저장소)에 있는 로그인 유저들을 추적한다.
클라이언트가 로그인 요청을 보낸다.
서버는 credentials를 검증하고, session을 생성해 현재 유저에게 배정된 메모리에 저장한다.
그리고 session id를 생성해 응답해준다.
클라이언트는 session id를 받아 쿠키나 로컬/세션 스토리지에 저장한다.
클라이언트는 다음 요청을 session id와 함께 보낸다. 서버는 저장소에 현재 session id의 유저가 있는지 확인하고 응답한다.
유저가 로그아웃하면 서버는 세션을 삭제한다. 동일한 session id는 재사용할 수 없다.
요청마다 credentials(username, password)를 보내는 Basic Auth 방식과 다르게, 매 요청에서 토큰(token)을 보내는 방식이다.
Authorization header
로 보낸다.클라이언트는 토큰을 생성하기 위한 credentials를 서버에 보낸다.
서버는 credentials를 검증하고 응답한다.
클라이언트는 토큰을 로컬 스토리지나 쿠키에 저장하고, 차후 요청에 보낸다.
서버는 토큰을 검증하고, 토큰이 유효한지 응답한다.
Token Based 인증 방식의 하나로 Open Standard(RFC 7519)에 기반한다.
인증과 안전한 정보 교환에 사용된다.
다른 토큰 인증 방식처럼 구분자(diffrentiator)만이 토큰이 생성된 방식을 알 수 있다.
클라이언트는 유저의 credentials를 서버로 보내 토큰 발급을 요청한다.
서버에서 credentials를 검증한다.
서버는 secret key를 사용해 JWT(JSON Web Token)을 생성한다.
생성한 JWT를 클라이언트에 보내준다.
클라이언트는 보호된 endpoint에 접근할 때 JWT를 요청 헤더에 포함한다.
서버는 secret key를 사용해 JWT를 검증한다.
검증된 JWT라면 클라이언트의 리소스 요청에 응답한다.
URL-Safe 문자열. header/body 혹은 URL을 통해 서버로 전달된다.
토큰은 데이터를 포함할 수 있는 등 self-contained. 누구나 볼 수 있다.
다음 세가지 파트로 이루어져 있다.
토큰 payload에 담긴 데이터를 claims라고 한다.
userId, email 등 사용자 정의 claims
토큰의 공급자, 소유자 이외에게 의미없는 claims
예약된 claims
유저가 서드파티에 개인정보 공유를 허용하는 오픈 프로토콜 인증 전략
프론트엔드에서 API로부터 인증하는 방식
타 서비스로 로그인하는 방식
4가지 인증 플로우(허가 방식)가 있다.
모든 플로우에서 클라이언트는 토큰으로 보호된 리소스에 접근한다.
클라이언트가 토큰을 요청한다.
인증 서버는 클라이언트를 검증하고 유저에게 로그인 양식을 제공한다.
유저는 로그인 양식을 통해 인증 서버에게 로그인을 요청한다.
인증 서버는 유저의 credentials를 검증하고, 유저가 공개할 정보의 범위를 물어본다.
유저는 인증 서버의 범위에 대한 정보 접근을 허용한다.
인증 서버는 클라이언트에게 인증 코드와 리다이렉트 URI를 준다.
클라이언트는 인증 코드, 유저 정보로 인증 서버에게 토큰을 요청한다.
인증 서버는 검증 후 클라이언트에게 토큰을 준다.
클라이언트는 토큰을 통해 보호된 리소스에 접근하고 응답받는다.
{
client_id: [client_id],
response_type: code,
scope: [scopes],
redirect_uri: [redirect_uri],
state: [redirect_uri]
}
{
client_id: [client_id],
response_type: token,
scope: [scopes],
redirect_uri: [redirect_uri],
state: [redirect_uri]
}
{
client_id: [client_id],
response_type: token,
scope: [scopes],
redirect_uri: [redirect_uri],
state: [redirect_uri],
grant_type: [token]
}
{
client_id: [client_id],
response_type: token,
scope: [scopes],
redirect_uri: [redirect_uri],
state: [redirect_uri],
grant_type: [password]
}
여러 독립적인 서비스들에서 유저가 단일한 username, password로 로그인하게 해주는 전략
ex. Gmail 로그인으로 모든 google product 이용
SSO가 없다면 구글의 모든 서비스에 각각의 credentials로 로그인해야한다.
관계자(party) 간 인증, 인증 정보를 교환하는 Open Standard
User : 리소스에 접근하고자 하는 주체
Identity Provider(IDP) : 어떤 유저가 있고, 유저가 무엇을 할 수 있는지
Service Provider(SP) : 어떤 접근을 허용할지
XML 문서
Configuration: 필요한 자원 정보
Certificates: assertion을 검증해줌으로써 데이터가 신뢰할 수 있음을 보장한다.
클라이언트가 IDP에게 인증 요청
유저가 IDP에게 요청을 시작한다.
IDP는 유저에게 인증을 요구한다.
유저는 IDP에게 credentials를 보낸다.
IDP는 credentials가 검증되지 않으면 reject하고, 검증되면 SAML assertion을 보내준다.
IDP에게 받은 SAML assertion을 SP에 보낸다.
SP는 SAML assertion을 검증하고, 검증되면 세션이 시작된다.
클라이언트가 SP에게 인증 요청
Identity Provider Initiated Flow와 같지만, 첫번째 요청이 SP로부터 온다.
즉, SP가 먼저 유저를 IDP에서 인증하도록 한다.
Basic Authentication
Session Based Authentication
Token Based Authentication
JWT Authentication
OAuth
SSO - Single Sign On