OAuth 2.0 FundamenTals(2)

Crow·2022년 11월 23일
0

InflearnOAuth2

목록 보기
7/12

2.OAuth 2.0 용어 이해

1. Keycloak 설치 및 설정

keycloak 소개 및 설치

  • ID 및 접근 관리를 지원하는 인가서버 오픈 소스로 사용자 연합, 강력한 인증, 사용자 관리, 세분화된 권한 부여 등을 제공함

  • https://www.keycloak.org/downloads

keycloak 시작하기

  • 본 강의에 있어 OAuth2 Client와 Resource Server 커리큘럼에서 인가서버 플랫폼으로 사용함

  • Keycloak에 대한 자세한 내용은 공식 문서를 참고해서 공부할것(나는 지금 KeyClak 부분은 빠르게 넘어가야겠음)// 23년 1월 20일 내용 보충중

  • intelliJ Terminal에서 keycloak\bin 파일안으로 이동후 .\kc.bat start-dev 해당 명령어 입력 실행 성공시 8080포트로 실행됨(내 버전은 keycloak 20.0.1임)
    (실행 실패시 java Home path잡을것 그래도 안될시 jdk 11 or 17 사용)

Postman

2. OAuth 2.0 Roles

-OAuth 2.0 메커니즘은 다음 네 가지 종류의 역활을 담당하는 주체들에 의해 이루어지는 권한 부여 체계이다.

  1. Resource Owner (자원 소유자)

    • 보호된 자원에 대한 접근 권한을 부여할 수 있는 주체, 사용자로서 계정의 일부에 대한 접근 권한을 부여하는 사람
    • 사용자를 대신해여 작동하려는 모든 클라이언트는 먼저 사용자의 허가를 받아야한다.
  2. Resource Server (보호 자원 서버)

    • 타사 어플리케이션에서 접근하는 사용자의 자원이 포함된 서버를 의미한다.
    • 액세스 토큰을 수락 및 검증할 수 있어야 하며 권한 체계에 따라 요청을 승인할 수 있어야한다.
  3. Authorization Server(인가 서버)

    • 클라이언트가 사용자 계정에 대한 동의 및 접근을 요청할 때 상호 작용하는 서버로서 클라이언트의 권한 부여 요청을 승인하거나 거부하는 서버
    • 사용자가 클라이언트에게 권한 부여 요청을 승인한 후 access token을 클라이언트에게 부여하는 역활
  4. Client (클라이언트)

    • 사용자를 대신하여 권한을 부여받아 사용자의 리소스에 접근하려는 어플리케이션
    • 사용자를 권한 부여 서버로 안내하거나 사용자의 상호 작용 없이 권한 부여 서버로부터 직접 권한을 얻을 수 있다.

Keycloak + post맨을 사용해서 Openid의 userinfo를 가져오는 과정(KeyCloak 20.0.1버전사용중)

  1. .\kc.bat start-dev 해당 명령어 입력해서 KeyCloak 실행

  2. localhost:8080/접속

  3. 왼쪽 탭에 master 클릭후 Create Realm 클릭이후 Realm name에서 원하는 이름으로

  4. 해당 realm의 clients 탭에서 Create client해주면됨

  5. Client ID & Name을 동일하게 설정(나는 test-oauth2-client로 만듬)
    next클릭후 Capability config 항목에서 Client authentication = On으로 / Service accounts roles 체크하기

  6. Settings에서 Valid redirect URIs설정(리다이렉트 uri를 설정하는것임
    나는 강의와 같은 http://localhost:8081 사용)
    아래 사진처럼 설정

  1. Users -> Add user를 통해서 유저추가(다른건 원하는대로 설정하고 Enabled만 ON으로 생성후 Users에서 해당 유저 클릭후 Credentials 항목에서 password 설정해줄것)

  2. PostMan을 통해서 아래의 사진처럼 Get으로 uri & Key값 설정 value값은 설정한대로 하면됨

  3. 로그인 후 사용자의 권한 동의 페이지가 뜨는지 확인

    위의 화면이 없을시 6번의 사진처럼 생성한 클라이언트 설정

  4. 로그인후 받은 코드를 이용해서 액세스 토큰을 받기 위해서 PostMan에 Post로 요청을 보내줌
    client의 Credentials에서 Client secret 값 필요
    getCode를 통해서 얻은 코드도 같이 보내주면됨(코드는 만료 기간이 존재해서 너무 오래된 코드라면 다시 로그인해서 얻어야함)

POST 방식을 이용하기 때문에 Body에 해당 내용을 담아줘야함

  1. 받은 access_token을 이용해서 resource 서버에 유저 정보를 요청해서 받으면됨

해당 실습중 Keycloak 이 20+버전이라 userinfo를 가져올때 403 오류 발생

해당 문제는 처음에 로그인을 해서 code를 가져올때 openid scope를 추가해주면 해결됨
이 페이지엔 추가해서 적어둠

3. OAuth 2.0 Client Types

  • 개요

    • RFC 6749 - https://datatracker.ietf.org/doc/html/rfc6749#section-2.1

    • 인증서버에 클라이언트를 등록할 때 클라이언트 자격 증명인 클라이언트 아이디와 클라이언트 암호를 받는다.

    • 클라이언트 암호는 비밀이고 그대로 유지되어야 하는 반면 클라이언트 아이디는 공개이다.

    • 이 자격 증명은 인증 서버에 대한 클라이언트 ID를 증명함

기밀 클라이언트 (Confidential Clients)

  • 기밀 클라이언트는 Client_secret의 기밀성을 유지할 수 있는 클라이언트를 의미한다.
  • 일반적으로 사용자가 소드 코드에 액세스 할 수 없는 서버에서 실행되는 응용 프로그램으로 NET,Java,PHP 및 Node JS와 같은 서버 측 언어로 작성된다.
  • 이러한 유형의 애플리케이션은 대부분 웹 서버에서 실행되기 때문에 일반적으로 웹 앱 이라고 한다.
  • 보통 기밀 클라이언트로 권한 부여 요청을 한다
    (특별한 경우를 제외하곤 당연히 기밀 클라이언트 사용)

공개 클라이언트 (Public Clients)

  • 공개클라이언트는 Cluent_secret의 기밀을 유지할 수 없으므로 이러한 앱에는 secret이 사용되지 않는다.
  • 브라우저(SPA)에서 실행되는 JavaScript 애플리케이션, Android 또는 IOS 모바일 앱, 데스크톱에서 실행되는 기본 앱 뿐만 아니라 IoT/임베디드 장치에서 실행되는 애플리케이션 등이 있다.
  • Chrome 개발자 콘솔이나 디스어셈블러와 같은 디버깅 도구를 사용하여 바이너리/실행코드에서 기밀정보를 추출할 수 있기 때문에 공개로 간주된다.
  • 서버측이 아닌 리소스 소유자가 사용하는 장치에서 실행되는 모든 클라이언트는 공개 클라이언트로 간주되어야 한다.
  • 때에 따라서 기밀성 유지가 필요가 없다고 판단하면 사용됨

Implicati flow(deprecated)

public client의 흐름

public client는 front channel에서만 인가 서버와의 상호 작용이 일어나며 서버측 과의 상호 작용은 일어나지 않음

client가 인가서버(Auth Server)에 권한 부여를 요청하며 바로 액세스 토큰을 발급해줌

하지만 confidential client에서 액세스 토큰발급은 최종적인 단계이며
프론트 채널에서 액세스 토큰을 발급하는 자체로도 탈취 당할 가능성이 생기기 때문에 현재는 deprecated됨

authorization code flow

confidential client의 흐름

front channel & back channel 두 채널 모두와 상호작용이 일어남

먼저 front channel에선 client가 권한 부여를 요청시 인가 서버(Auth Server)는 토큰 대신 Code를 발급해줌

Back Channel에서 해당 Code를 가지고 다시 Auth Server에 가서 한번 더 해당 코드의 유효성 검사를 통과해야지 토큰을 발급해준다.

이때 Client Secret을 Code와 같이 전달하기 때문에 기밀성을 유지하며
사용자가 Client Secret을 알기 여려움


공개 클라이언트를 활용이용해서 토큰 가져오기

  1. 클라이언트 설정에서 Implicit flow(묵시적 흐름) 체크하고 저장해줌

  2. Post 맨에서 url 수정 이후 브라우저에서 해당 url을 사용해서
    인증 요청

  3. 발급 받은 토큰 확인

  4. PostMan userInfo에서 토큰을 사용해서 사용자 정보 가져오기

앞에서 말했듯이 공개 클라이언트는 Client Secret을 사용할 수 없고 액세스 토큰을 바로 발급해주기 때문에 토큰 자체를 탈취하기 쉬워서 너무 큰 보안 취약점이 생기기 때문에
Deprecated된걸 느낄 수 있다.

4. OAuth 2.0 Token Types

1. Access Token

  • Client에서 사용자의 보호된 Resource에 접근하기 위해 사용하는 일종의 자격 증명으로서 역활을 하며 Resource 소유자가 Client에게 부여한 권한 부여의 표현이다.
    • Client가 사용자의 Resource Sever에게 사용자의 자원을 요청할때 반드시 Access Token이 필요하다
    • 이때 리소스 서버는 Client가 들고온 토큰에서 해당 자원에 대해 권한이 있는지 없는지를 확인하고 검증 이 토큰이 정상적인 토큰이라면 자원을 클라이언트에 제공해준다.
    • 그렇기 때문에 토큰 자체가 일종의 자격 증명 역활을 한다.
  • 일반적으로 JWT(JSON Web Tokens)형식을 취하지만 사양에 따라 그럴 필요는 없다(요즘엔 거의 다 JWT 형식을 취함)
  • 토큰에는 해당 액세스 기간, 범위 및 서버에 필요한 기타 정보가 있다.
  • 타입에는 식별자 타입(Identifier Type)과 자체 포함 타입(Self-contained Type)이 있다.

Access Token 유형

식별자 타입(Identifier Type)

  • 인가서버는 데이터 저장소에 토큰의 내용을 저장하고 이 토큰에 대한 고유 식별자만 클라이언트에 다시 발행한다.

  • 이 토큰을 수신하는 API는 토큰의 유효성을 검사하기 위해 인가서버에 대한 백채널 통신을 열고 DB를 조회한다.

    • 하지만 Client가 요청을 할때마다 통신을 열고 DB를 조회해야하기 때문에 통신비용이 증가하는 단점이 존재함

자체 포함 타입 (Self-contained Type)

  • JWT 토큰 형식으로 발급되며 클레임 및 만료가 있는 보호된 데이터 구조이다.

  • 리소스 서버 API가 검증 키 등의 핵심 자료에 대해 알게 되며 발급자와 통신할 필요 없이 자체 포함된 토큰의 유효성을 검사할 수 있다.

  • 특정한 암호화 알고리즘에 의해 개인키로 서명되고 공개키로 검증할 수 있으며 만료될 때까지 유효하다.

2. Refresh Token

  • 액세스 토큰이 만료된 후 새 액세스 토큰을 얻기 위해 클라이언트 응용 프로그램에서 사용하는 자격 증명
  • 액세스 토큰이 만료되는 경우 클라이언트는 권한 부여 서버로 인증하고 Refresh Token을 전달한다.
  • 인증 서버는 Refresh Token의 유효성을 검사하고 새 액세스 토큰을 발급한다.
  • Refresh Token은 액세스 토큰과 달리 권한 서버 토큰 엔드포인트에만 보내지고 리소스 서버에는 보내지 않는다.

3. ID Token

* ID 토큰은 OpenID Connect(OIDC) 사양을 준수하는 JSON 웹 토큰(JWT)입니다. 클레임이라는 키-값 쌍 집합으로 구성됩니다.

* 애플리케이션이 검사할 수 없는 불투명 객체인 액세스 토큰과 달리 ID 토큰은 애플리케이션에서 검사하고 사용하도록 되어 있습니다. 토큰에 서명한 사용자 또는 ID 토큰이 발급된 ID와 같은 토큰의 정보가 애플리케이션에서 사용하도록 제공됩니다.

* 자세한 설명은 다른 챕터에서

4. Authorization Code

* `권한 부여 코드 흐름에서 사용되며 이 코드는 클라이언트가 액세스 토큰과 교환할 임시 코드이다.`

  * 여기서 발급 받은 코드들은 1회용이며 사용후 폐기된다.

* 사용자가 클라이언트가 요청하는 정보를 확인하고 인가 서버로 부터 리다이텍트 되어 받아온다.

Reference

https://www.inflearn.com/course/%EC%A0%95%EC%88%98%EC%9B%90-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/

https://keycloak.discourse.group/t/issue-on-userinfo-endpoint-at-keycloak-20/18461/5

profile
어제보다 개발 더 잘하기 / 많이 듣고 핵심만 정리해서 말하기 / 도망가지 말기 / 깃허브 위키 내용 가져오기

0개의 댓글