[Keycloak] Authorization code방식의 인증 흐름

Kai·2022년 12월 23일
3

스프링과 OAuth2

목록 보기
3/11

☕ 시작


이번 글에서는 Keycloak의 엔드포인트들을 이용해서 Authorization code의 인증이 실제로 어떤 흐름으로 이루어지는지 알아보자.

Keycloak의 개념이나 Keycloak의 설치 및 실행에 대한 내용은 이전 글을 참고하자.


🧐 Authorization code 인증?


OAuth2표준에는 다양한 인증 방식이 정의되어있다.
그 중, Authorization code 방식은 가장 범용적으로 사용되는 인증방식이다.

사용자가 로그인(인증)을 하면 Access tokenRefresh token을 발급하고, 이 Access token을 갖고 여러 자원에 접근하는 방식이다.
자세한 내용은 이전에 글을 쓴 적이 있어서 이 글을 참고하자.


⚡ Keycloak 엔드포인트


Keycloak을 포함한 모든 인증서버들은 OAuth2 표준을 기반으로 만들어진다. 그리고 OAuth2에 필요한 기능들이 API형태로 제공된다.
그렇다면, OAuth2의 각 기능들이 Keycloak에서는 어떤 엔드포인트로 만들어졌는지 알아보자.

1) Realm생성

기본적으로 master Realm이 있지만, 새롭게 Realm을 만들어보자.
Keycloak을 로컬에서 실행시키고, 관리자 콘솔로 접속하면 아래와 같이 Realm을 생성할 수 있다.

(이하 모든 내용은 새롭게 생성한 Realm에서 진행한다.)

2) 엔드포인트 목록

(사이드 바) > Realm settings에 접속하면 위와 같이 엔드포인트를 전부 확인할 수 있는 링크를 제공한다.
해당 링크를 눌러보자.
그러면 엔드포인트들이 쫙 출력될 건데, 출력된 엔드포인트 중에서 중요한 것들을 한번 짚고 넘어가 보겠다.

브라우저에서 json 문자열을 예쁘게 보고 싶다면 json formatter라는 크롬 확장프로그램을 설치해주자.

3) issuer

{base url}/realms/{realm name}

Issuer 는 해당 Realm을 가리키는 url이라고 보면 된다. 하위 경로들은 대부분 정해진 규칙대로 비슷하게 형성되므로, 이 url만 알면 해당 Realm을 통해서 인증/인가 처리를 할 수 있다.
실제로 Spring security를 사용할 때에도 설정파일에 issuer url만 추가해주면 OAuth2기능들이 동작한다.

4) authorization_endpoint

{base url}/realms/{realm name}/protocol/openid-connect/auth

이 엔드포인트는 말 그대로 인증을 받는 URL이다.
이 url은 필수적으로 아래의 파라미터들을 기본적으로 포함해야 정상적인 접근이 가능하다.

  • response_type: 인증에 성공했을 때, 어떤 값을 응답값으로 받을 것인지
  • client_id: 인증절차를 거칠 Realm에 생성된 클라이언트의 id
  • redirect_uri: 인증에 성공한 후, redirect될 url
  • scope: 인증을 통해서 조회할 데이터의 범위를 설정

예시
http://localhost:9090/realms/oauth2/protocol/openid-connect/auth?response_type=code&client_id=oauth2-client-app&scope=profile email openid&redirect_uri=https://naver.com

5) token_endpoint

{base url}/realms/{realm name}/protocol/openid-connect/token

Access token과 Refresh token을 수령하는 url이다. 위에서 받은 code를 이 엔드포인트로 넘겨주면, 해당 사용자에 맞는 토큰들을 응답해준다.

6) userinfo_endpoint

{base url}/realms/{realm name}/protocol/openid-connect/userinfo

위에서 받은 Access token을 헤더에 실어서 이 url에 요청하면, Access token에 해당하는 user의 정보를 응답해준다.

그 외

위에서 살표본 엔드포인트들이 Authorization code형식으로 인증을 받기위한 최소한의 엔드포인트들이다.
나머지 엔드포인트들은 설명은 생략하도록 하겠다!


💻 로그인(인증)하기


시작하기 전에 준비물이 필요하다.
postman이라는 http요청 클라이언트를 먼저 내 pc에 설치하자.

🌊 흐름

실습할 인증 흐름은 다음과 같다.

  1. authorization_endpoint에 접속해서 code값 수령
  2. 수령한 code값으로 token_endpoint에 요청
  3. Token수령
  4. 수령한 Token으로 userinfo_endpoint에 사용자 정보 요청
  5. 사용자 정보가 응답되는 것을 확인
  6. (Access token이 만료됐다는 가정하에) 3번에서 받은 Refresh token으로 Access token갱신
  7. 갱신된 Access token수령

1) redirect uri 설정하기

authorization_endpoint 엔드포인트에 접근하기 위해선 redirect_uri를 필수적으로 설정해야한다.
아무거나 할 수 없고, 관리자 콘솔에서 미리 정의된 redirect_uri만 설정해야한다.

아래와 같이 redirect_uri를 설정하자.
나는 네이버..로 하겠다 ㅎ
실제로는 code값을 받아서 처리할 수 있는 곳을 redirect uri로 설정하면 된다.

2) 로그인하기

브라우저로 아래의 경로에 접속하자.

{base url}/realms/{realm name}/openid-connect/auth?response_type=code&client_id=o{client id}&scope=profile email openid&redirect_uri={redirect uri}

나의 경우엔 아래의 경로로 접속하면 된다.

http://localhost:9090/realms/oauth2/protocol/openid-connect/auth?response_type=code&client_id=oauth2-client-app&scope=profile email openid&redirect_uri=https://naver.com

그러면 이렇게 로그인 화면이 뜨는데, 여기에 로그인을 하자.
아! 로그인을 하려면, 해당 클라이언트에서 사용자를 미리 생성해주어야한다.
사용자는 Users메뉴에서 생성할 수 있다.

3) code 받기

로그인에 성공하면, 아래와 같이 파라미터로 넘겨준 redirect uri로 redirect되고, url 파라미터에 code값이 붙어있다.

이 code값을 일단 메모장에 복붙해놓자.

4) Access token 받기

이번엔 미리 설치한 Postman을 실행하자.
그리고 아래와 같은 요청을 만들자.

여기서 body로 넘기는 파라미터들 중에서 code에 이전단계에서 획득한 code값을 입력해주면 된다.
또, scope는 code를 받을 때, 설정한 scope값과 꼭 동일해야한다.

위와 같이 요청을 만들고 전송하면 아래와 같이 토큰들을 획득할 수 있다.

여기서 access token과 refresh token은 잘 갖고 있자.

5) 사용자 정보 조회하기

위와 같이 사용자 정보를 조회하는 엔드포인트에 맞는 요청을 생성한 후, 전송해보면 성공적으로 유저 정보가 응답된 것을 확인할 수 있다.

⭐ 여기서 Authorization 헤더의 값은 아래와 같이 생성해주면 된다.

Bearer {위에서 획득한 엑세스 토큰}

6) 토큰 갱신

Access token은 만료기간이 있다. 보통 Access token의 만료기간을 10분에서 1시간정도로 짧게 설정한 후, 클라이언트 측에서 주기적으로 갱신을 해주는 형태로 많이 사용한다.

이 때 Access token갱신은 4번에서 획득한 Refresh token으로 할 수 있다.
갱신을 위한 엔드포인트는 4번과 같으나, 파라미터가 좀 달라진다.

grant_type을 refresh_token으로 설정하고, refresh_token이라는 새로운 파라미터를 추가하고 그 값은 4번에서 획득한 Refresh token을 입력한다.

그러면 아래와 같이 새로운 토큰들을 다시 발급받을 수 있게 된다.


🤸‍♂️ 정리


이번 글에서는 OAuth2표준을 기반으로 만들어진 Keycloak의 엔드포인트를 토대로 authorization_code방식의 인증절차를 따라가보았다.
이러한 흐름은 Keycloak만의 흐름이 아니라 OAuth2표준에 정의된 흐름이다. 그래서 각 개발언어 마다 이를 알아서 구현해준 많은 라이브러리와 프레임워크들이 존재한다.

Spring security에서는 OAuth2Client라는 것으로 이 기능을 제공하고 있다.

아무튼 원격 인증서버를 통해서 로그인을 하는 방법을 알아봤으니, 이 서버를 커스텀하고 EC2에 배포하는 과정까지 한번 알아보도록 하자.

최대한 빨리 다음 글로 돌아오도록 하겠다.

0개의 댓글