728x90
OAuth2(Open Authenticaiton, Open Authorization)
- 표준 인증 프로토콜이다.
- 사람들은 타 사이트의 비밀번호를 제 3의 서버에서 노출하기를 꺼린다.
- → 노출되며 다른 정보도 노출 될 것이 자명하기 때문.
- 사용자가 타 사이트의 비밀번호를 변경하게 되면 제 3의 서버에 저장된 비밀번호도 바꿔야 해서 정상적인 서비스가 불가능하다.
주요 용어
- Resource Owner : 서비스를 이용하는 사용자, 즉 리소스 보유자
- Client : Resource Server에 자원을 요청하는 제 3 서버, RO를 대신하여 리소스를 요청한다.
- Resource Server : 클라이언트의 요청을 수락하고 응답할 수 있는 서버, ex) 네이버, 카카오 등
- Authorization Server : 성공적으로 인증한 후 액세스 토큰을 발급하는 서버
토큰 요청 방법 4가지
- Authorization Code grant
- Implicit Grant
- Client Credentials Grant
- Resource Owner Passsword Credentials Grant
1. Authorization Code Grant
- 사용자 인증
- code callBack
- client-id, client-secret으로 토큰 교환 ⇒ Access Token이 외부로 노출되지 않음
- Authorization Server ↔ Client 로 교환하기 때문
처리 Flow
1. Authorization Request
- 클라이언트가 RO를 Authorization 서버로 리다이렉션 한다.
- request 요청에 전달되는 query String
- response_type : code → 고정
- client_id : 클라이언트 식별 키 → Authorization을 요청하는 서버에서 발급받는다.
- redirect_uri : redirect URL
- scope : 요구 리소스 (이름, 성별, 나이, 이미지 등등)
- state : csrf 방지 토큰
2. Authorization Response
- 로그인 및 사용자 인증을 진행하는 과정
- Authorization request에서 받은 redirect_uri를 이용해 인증 서버로 리다이렉션한다.
- 이때, code와 state를 같이 보내준다.
3. Token Request
- 응답받은 code를 이용하여 Access-token 을 교환하는 과정
- 이때, writing 이라는 header에 여러 값을 전달한다.
- grant_type : authorization_code → 고정
- code : 기존의 code와 동일
- client_id : 토큰 발급 서버에서 클라이언트 식별을 위한 식별 키
- client_secret : client 비밀 키이다. → Authorization을 요청하는 서버에서 발급받는다.
4. Token Response
- AccessToken 및 부가 정보를 제공한다.
- access_token : 리소스 요청에 필요한 토큰이다.
- refresh_token : access-token을 갱신하기 위한 토큰이다.
참고) Refresh Token
- Access Token이 사용자 정보를 확인 할 수 있는 토큰이라면, Refresh Token은 용어 그대로 Access Token을 재 발급 해주는 토큰이다.
- 주로, 자동 로그인 혹은 로그인 유지에 사용이 된다.
- Access Token은 토큰 만료시간이 되기 전까지 Access Token을 이용하여 이용 권한을 획득하는 형태이기 때문에 만료 시간을 길게 책정하면 안된다.
- 따라서, 이러한 Access Token을 빠르게 발급해주기 위해 Refresh Token을 사용하고, Refresh Token의 존재에 따라 Access Token을 다시 빠르게 발급 받을 수 있다.
- 이렇듯, Access Token의 만료시간은 빠르고 재 발급 해줄 때마다 Refresh Token의 유효성 검증이후 재발급 요청 API를 호출하기 때문에 DB에서 값을 탐색하는데 있는 잦은 IO 작업으로 성능상의 문제가 발생한다. 이러한 이유로 인 메모리 DB를 사용한다.
- 주의해야 할 점은 Refresh Token을 갈취당하면 고객 정보가 그대로 노출되기 때문에 Refresh Token은 최대한 감추는 것이 중요하다. 또한 Refresh Token은 로그아웃을 시도하면 삭제가 되어야 한다.
2. Implicit Grant
- 보안상 문제가 있는 요청 방식이다.
- Authorization Code Grant에 방식 중 token Request, Response 방식이 빠진 형태이다.
- url의 queryString으로 AccessToken을 같이 보내주는 형식
- 따라서, 백엔드 서버가 없이 자바 스크립트로만 돌아가는 웹 앱에서 주로 사용된다.
여기서 주의해야 할 점은 토큰을 반환해 줄때 Url에 같이 담겨서 온다는 것이다.
3. Client Credentials Grant
- 이전까지의 요청들이 RO가 요청하여 수행되는 동작이라면 이 방식은 RO의 요청없이 이루어진다.
- client가 client_id와 client_secret을 안전하게 보관한다는 가정하에 id와 secret을 이용하여 인증 서버와 통신한다.
- 클라이언트의 자격증명만으로 이루어지기 때문에 권한 서버에 클라이언트를 위한 접근 권한이 설정되어 있어야만 하고, Refresh Token을 사용할 수 없다.
→ 주로 백 그라운드 방식으로 많이 사용된다.
4. Resource Owner Password Credentials Grant
- RO의 username과 password로 Access Token을 발급 받는 형태이다.
- 만약 클라이언트가 타사의 외부 프로그램일 경우에 적용하면 안되며, 동일한 서비스에서 제공하는 경우에만 이 방식을 채택해야 한다. 즉, 클라이언트, 권한 서버, 리소스 서버가 모두 동일한 서비스여야 한다는 것이다.
OAuth2 구현의 개선
Spring Boot 3.1.2, Spring Security 6을 사용하였습니다.
AuthorizationRequestRepository는 OAuth2 요청 간 인증 상태를 유지 시키기 위해 사용한다. Jwt는 Stateless 방식을 최적화하기 위하여 사용을 하는데 현재 기본 구현체가 HttpSessionOAuth2를 사용하는 것을 볼 수 있다. 이를 위해 Session을 사용하지 않고, Cookie 형식으로 변환하고자 한다.
다음과 같이 Cookie를 통하여 인증 상태를 유지시키도록 하기 위해 AuthorizationRequestRepository를 구현하였다.
두 가지 핵심 구현 로직을 살펴볼 수 있다. 기본적으로 Jwt사용시 base64 인코딩 방식을 택하므로 Base64로 인코딩을 해주어 쿠키에 전달하고, 응답시에는 decode를 통해 객체로 반환하여 전달을 해준다.
참고) 스프링 프레임워크에서 사용하는 SerializationUtils.deserialize는 deprecated 되었다. 스프링에서는 원격 수정에도 안전한 다른 third party 라이브러리를 권장하는데, 이를 위해 apache.commons.lang3을 사용하면 검증 이후 decoding을 진행하는 부분이 있어 해당 부분을 사용하도록 하자.
'Backend > Spring' 카테고리의 다른 글
막내 개발자의 사내 분산 락 라이브러리 도입이야기 (1) (2) | 2024.11.10 |
---|---|
Spring Security 5 -> Spring Security 6 에서의 Session 변경점 (0) | 2023.08.20 |
Invalid character found in method name 에러 (2) | 2023.05.07 |
Spring AOP (0) | 2023.04.26 |
스프링의 빈 후처리기 (0) | 2023.04.24 |