ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OAuth 2.0 API 보안] OpenID 커넥트 (OIDC)
    보안/OAuth 2.0 2022. 6. 7. 14:12

    참고할 만한 자료

     

    Microsoft ID 플랫폼 및 OpenID Connect 프로토콜 - Microsoft identity platform

    OpenID Connect 인증 프로토콜에 대한 Microsoft ID 플랫폼 구현을 사용하여 웹 애플리케이션을 빌드합니다.

    docs.microsoft.com

    OAuth 2.0 및 OIDC 정의

     

     

    Final: OpenID Connect Core 1.0 incorporating errata set 1

     

    openid.net

    OIDC 핵심 사양

     

     

    OAuth 2.0 Playground

    Request Body Manual entry Enter the data that will be added to the body of the request: File You may choose to send a file as part of the request. When both a file and manual content are provided both will be sent using a multipart request. You may send fi

    developers.google.com

    OAuth 2.0와 OAuth 2.0 기반 실습

     

     

    Deliver Seamless Login Experiences with WSO2 Identity Server

    WSO2 Identity Server offers the best end-to-end developer experience to create seamless login experiences. It helps federate, authenticate and unify identities, bridge identity protocols across environments, and secure access to web, mobile apps, and API-b

    wso2.com

    오픈소스 ID 및 권한 관리 서버

     


    1. OpenID 커넥트 (OIDC)

    OIDC는 RESTful 방식의 가벼운 프레임워크를 제공하는 표준이다.

    OpenID에 기반을 두고 있지만 OAuth 2.0의 영향을 받았다.

     


    2. From OpenID to OIDC

    OpenID와 SAML은 기본적으로 웹 SSO와 도메인 간 ID 연동을 쉽게 해준다.

    이 중, OpenID는 커뮤니티 친화적, 사용자 중심, 분산의 특징을 가진다.

    여기서 OpenID와 OAuth 1.0은 각각 다음의 내용을 처리한다.

    • OpenID : 인증
    • OAuth 1.0 : 위임된 권한

     

    따라서, 표준을 결합하여 사용자 인증과 리소스 접근 토큰 발급을 동시에 얻는 방법을 의미한다.

    • 1세대 : OpenID 1.0 / 1.1 / 2.0
    • 2세대 : OAuth OpenID
    • 3세대 : OpenID Connect (OAuth 2.0의 확장)
    OAuth 2.0에 기반한 OIDC

     

    OIDC는 OpenID보다는 동작 프로토콜에 가깝다.

    OpenID는 여러 웹 서비스에서 흩어져 있는 개인 사용자의 프로필을 하나로 통합하고 관리할 수 있도록 한다.

     


    3. OIDC 이해

    앞서 확인한 것 처럼 OIDC는 OAuth 2.0의 위에 ID 계층을 도입한 형태로 구축됐다.

    이 OIDC를 위한 계층은 JWT 토큰으로 추상화된다.

    OIDC를 지원하는 OAuth 2.0 인가 서버는 액세스 토큰과 ID 토큰을 함께 발급한다.

     

    여기서, OAuth 2.0은 인가를 관리하고 OIDC는 인증을 관리한다.

    → 인증이란 데이터나 엔티티 속성의 사실 여부를 확인한다. 즉, 신원을 확인한다.

    → 인가란 신원이 증명된 대상이 무엇을 할 수 있는지를 확인하는 것이다. 즉, 권한을 확인한다.

     

    이것에 기반해서 OAuth 2.0은 사용자의 정보와는 상관 없이 사용자를 대신해 자원에 접근하는 것이다.

    OIDC는 OAuth 2.0의 자원 위임과 더불어서 사용자의 신원까지 식별할 수 있다.

     


    4. ID 토큰

    ID 토큰은 OIDC를 위한 OAuth 2.0의 애드온이며 인증된 사용자 정보를 인가서버에서 클라이언트로 전송한다.

    이때의 형태는 JWT이다. 토큰을 암호화 할 수 있지만 JWE에 정의된 규칙을 통해 암호화한다.

    • 암호화 이전 서명을 선행한다.

     

    /* ID 토큰 예시 */
    {
    	"iss" : "<https://auth.server.com>",
    	"sub" : "sub@parameter.com",
    	"aud" : "as7a6FgFJ12k",
    	"nonce" : "887af9as8df",
    	"exp" : 1416284980,
    	"iat" : 1416284980,
    	"auth_time" : 1316284980,
    	"acr" : "urn:mace:incommon:iap:silver",
    	"amr" : "password",
    	"azp" : "as7a6FgFJ12k"
    }
    

    iss : HTTPS 형식의 토큰 발급자 식별값 (필수)

    • 쿼리 파라미터나 URL 프래그먼트가 존재하지 않는다.
    • ID 토큰의 필수 속성이며 원하는 발급자를 설정할 수 있다.

     

    sub : ID 토큰에 포함된 클레임을 식별하는 서브 파라미터 (필수)

    • 토큰 발급자는 특정 엔티티에 대한 ID 토큰을 발급한다.
    • 클레임은 이 특정 엔티티를 나타낸다.

     

    aud : Audience로 토큰을 바라보는 관점을 가진다. (필수)

    • 식별자에 관한 배열일 수 있다.
    • OAuth ClientID가 포함되어야 한다.
    • 만일 ClientID가 없다면 azp 파라미터를 추가한다.
    • 유효성 검사 수행 전 특정 ID토큰이 사용되기 위해 발급되었는지 확인하고 발급되지 않았다면 거부한다.

     

    nonce : 재전송 공격을 막기 위한 파라미터

    • OIDC에서 초기 인가 요청에서 등장한 파라미터
    • 클라이언트는 OAuth 2.0의 파라미터 외에 선택적으로 포함할 수 있다.
    • Nonce 값이 동일한 요청은 거부한다.

     

    exp : ID 토큰의 만료 시간 (필수)

    • 만료된 토큰은 거부한다.
    • 토큰 발급자의 시간대와 동기화 해야 유효성 검사에 실패하지 않는다.

     

    iat : ID 토큰의 발행 시간 (필수)

    • 토큰이 발행 될 때 현재 시간까지 경과된 시간(초)을 나타낸다.

     

    auth_time : 사용자가 인가 서버로 인증하는 시간

    • OID 클라이언트 이외의 앱에 처음 로그인을 시도할 때 인가 서버로 인증된 세션을 만들 수 있다.
      • 이 경우 인증된 시간을 유지하고 auth_time 파라미터를 추가한다.
    • 이미 인증된 경우 재인증 요청을 하지 않는다.
    • 인증법과 인증 세션 관리는 OIDC가 다루지 않는다.

     

    acr : 인증 콘텍스트 클래스 참조(Authentication Context class Reference)

    • 인가 서버와 클라이언트 애플리케이션에서 해석될 수 있다.
    • 인증의 레벨을 나타내는 값이며 브라우저 쿠키를 통한 인증은 레벨0다.
      • 레벨 0의 경우 금전적 가치가 있는 리소스에 접근하지 않는 것이 좋다.

     

    amr : 인증 방법 참조 (Authentication Method References)

    • 인가 서버가 사용자를 인증하는 방법이다.
    • 배열로 구성될 수 있으며 서버/클라이언트 모두 이 값을 해석할 수 있어야 한다.
    • 인증 방법을 명시한다.

     

    azp : 승인 당사자 (Authorized Party)

    • aud가 한 명이고 값이 OAuth ClientID와 다른 경우 필요하다.
    • OAuth ClientID 값으로 설정한다.

     


    5. OIDC 요청

    OIDC에서는 OAuth 2.0에 ID 토큰 외에도 다른 파라미터를 포함한다.

    또한, 모든 OIDC 요청은 scope로 openid를 명시해야한다.

    <https://localhost:9443/OAuth2/authorize>?
    	response_type=code&
    	scope=openid&
    	client_id=__CLIENT_ID__&
    	redirect_uri=https://localhost/callback&
    	response_mode=_____&
    	nonce=_____&
    	display=_____&
    	prompt=_____&
    	max_age=_____&
    	ui_locales=_____&
    	id_token_hint=_____&
    	login_hint=_____&
    	acr_value=_____
    

     

    response_mode : 인가 서버가 파라미터를 응답하는 방법 결정

    • OAuth 2.0의 핵심인 response_type과는 다른 개념이다.
    • query → redirect_uri에 추가된 쿼리로 클라이언트 응답
    • 프래그먼트 → 응답 파라미터가 redirect_uri에 추가

     

    nonce : 재전송 공격을 막기 위한 파라미터

    • Nonce 값이 동일한 요청은 거부한다.
    • 클라이언트는 ID 토큰 수신 후 nonce를 검증해야 한다.

     

    display : 클라이언트가 원하는 인가서버가 로그인/사용자 동의 페이지를 표시하는 방법

    • page, popup, touch, wap

     

    prompt : 인가 서버에 로그인/사용자 동의 페이지 표시 여부

    • 값이 없다면 표시되지 않는다.
    • 사용자는 인가 서버에서 인증된 세션과 사전에 설정된 사용자 동의가 필요하다.
    • login : 인가 서버는 사용자를 다시 인증
    • consent : 사용자 동의 페이지 표시
    • select_account : 여러 계정을 가진 경우 필요 계정을 선택

     

    max_age : ID 토큰의 auth_time과 비교할 값

    • max_age와의 비교에서 (현재 시간 - max_age)가 auth_time 보다 작다면 재 인증해야 한다.

     

    ui_locales : 사용자 인터페이스에 사용되는 언어

     

    id_token_hint : ID 토큰

    • 클라이언트에서 이전에 얻은 ID 토큰일 수 있다.
    • 암호화된 토큰은 먼저 암호 해독 후 인가서버의 공개키로 다시 암호화하여 인증 요청에 넣는다.
    • prompt 값이 none일 경우 필수는 아니다.

     

    login_hint : 사용자가 인가 서버에서 사용할 수 있는 로그인 식별자

    • 이메일 주소와 같은 값을 설정 가능하다.
    • 사용자의 접근성을 향상시킨다.

     

    acr_values : 인증 콘텍스트 참조 값 (Authentication Context Reference Values)

    • 인가 서버에서 필요한 인증 레벨을 나타낸다.
    • 공백으로 구분된 일련의 값을 포함한다.

     


    6. 사용자 속성 요청

    OIDC에서는 사용자 속성을 요청하는 두 가지 방법이 있다.

    1. 클라이언트 앱이 초기 OIDC 요청을 통해 속성을 요청
    2. 추후 인가 서버가 호스트하는 UserInfo 엔드포인트와 통신

     

    초기 인증 요청을 사용하면 클라이언트는 요청된 클레임을 파라미터에 포함한다.

    • OIDC는 20개의 표준 사용자 클레임을 정의한다.
    • 이 클레임들은 클라이언트/서버에서 해석될 수 있어야 한다.

     

    /*
    <https://localhost:9443/OAuth2/authorize>?
    			response_type=code&
    			scope=openid&
    			client_id=__CLIENT_ID__&
    			redirect_uri=https://localhost/callback&
    			claims=__아래의내용__
    */
    
    // 사용자의 이메일, 이름을 ID 토큰에 포함하도록 요청한다.
    {
    	"id_token" :
    		{
    			"email" : {"essential" : true},
    			"given_name" : {"essential" : true}
    		}
    }
    

    UserInfo 엔드포인트를 통해 사용자 속성을 요청할 수 있다.

    엔드포인트는 인가 서버의 OAuth 2.0으로 보호되는 자원이기에 모든 요청엔 유효 OAuth 2.0 토큰이 필요하다.

    • OAuth의 액세스 토큰 사용→ OIDC에서는 프로필, 이메일, 주소, 전화번호의 값이 있다.
      • 클라이언트는 인가 승인 요청에서 해당 속성의 범위를 지정해야 한다.
      • 즉, 우리가 인가를 승인하고 제공할 정보의 범위를 지정하는 것이다.

     

    scope=openid phone email&
    

    위 요청은 인가 코드가 응답된다.

    클라이언트 앱은 인가 코드를 가지고 인가 서버의 토큰 엔드포인트와 통신해 접근 코드로 교환한다.

    이 접근 코드를 통해 액세스 토큰을 사용하고 UserInfo 엔드포인트와 통신해 사용자 속성을 얻을 수 있다.

     


    7. OIDC 흐름

    인가 코드 승인 유형을 통해 ID 토큰을 요청할 수 있지만 필수는 아니다.

    OIDC는 OAuth 2.0의 승인 유형과는 독립적인 흐름을 가진다.

    response_type 파라미터의 값이 그 흐름을 결정한다.

    • 코드, 암시적, 하이브리드

     

    response_type 파라미터는 항상 인가 엔드포인트에 대한 요청과 함께 전송된다.

     

    이를 통해 엔드포인트의 응답을 결정한다.

    암시적인 흐름의 경우 response_type의 값은 “id_token”이나 “id_token token”일 수 있다.

    • “id_token” → 인가 엔드포인트에서 ID토큰을 반환한다.
    • “id_token token” → 인가 엔드포인트에서 ID토큰과 액세스 토큰을 반환한다.

     

    하이브리드 흐름의 경우 다음과 같은 조합도 사용할 수 있다.

    • “code id_token” → 인가 코드와 id_token
    • “code token” → 인가 코드와 액세스 토큰

    “code token”. 즉, 인가 코드와 액세스 토큰을 요청하는 경우 인가 코드를 UserInfo의 엔드포인트로 하여 액세스 토큰과 함께 반환된다.

    인가 코드, ID 토큰, 액세스 토큰 3가지 유형이 모두 포함된 경우로도 사용할 수 있다.

     


    8. 사용자 정의 사용자 속성 요청

    OIDC는 20개의 표준 클레임을 제공한다.

    이 클레임은 scope/claim 파라미터를 통해 요청할 수 있다.

    사용자 정의 클레임의 경우 claim 파라미터를 통해 요청할 수 있다.

     


    9. OIDC Discovery

    사용자가 제공하는 URL인 OpenID를 통해 OpenID의 신뢰 당사자가 OpenID 공급자를 알아낼 수 있다.

    또 다른 방식은 OIDC 디스커버리다.

    OIDC를 통한 사용자 인증 과정은 OIDC 신뢰 당사자가 사용자의 뒤에 어떤 인가 서버가 있는지 파악하는 것에서 시작한다. OIDC는 WebFinger 프로토콜을 통해 이를 파악한다.

     

    사용자가 OIDC를 통해 로그인하려면 OIDC의 로그인 서비스를 제공하는 신뢰 당사자는 사용자의 인가 서버를 알아야 한다. 이를 위해서 사용자는 OIDC 로그인 과정에서 자신의 고유 식별자를 제공해야 한다.

     

     

    resource=acct:user@email.com&
    rel=http://openid.net/specs/connect/1.0/issuer HTTP/1.1
    

     

    이 고유 값을 WebFinger의 엔드포인트로 전달하면 사용자의 인가 서버를 알 수 있다.

    • resource : 사용자 고유 식별자
    • rel : OIDC에 대한 고정 발행자

     

    이처럼 WebFinger를 통해 인가 서버와 같은 것에 대해 Discovery(발견) 요청을 할 수 있다.

    ID 공급자의 엔드 포인트를 찾는 것으로 WebFinger의 역할은 끝이 난다.

     

    하지만, OIDC 인증 요청을 시작하기에는 데이터가 부족하다.

    추가적으로 ID 공급자 정보, 클라이언트 앱의 등록 여부 등을 확인해야 한다.

     


    10. OIDC 공급자 메타데이터 검색 및 동적 클라이언트 등록

    그렇다면 WebFinger를 사용한 이후 필요한 ID 공급자 정보는 어떻게 얻을까?

    공개된 메타데이터 검색 종단점이 있으며 대부분 누구나 접근할 수 있다.

    이 엔드포인트를 통해서 OIDC 공급자 구성 세부 사항을 확인할 수 있다.

     

    기본적인 엔드포인트가 “https://url.com”이라면 OIDC 공급자의 메타데이터 검색을 위한 엔드포인트는

    https://url.com/.well-known/openid-configuration 이다.

     

    이런 형태로 OIDC 공급자에 대한 검색으로 OIDC 공급자 엔드포인트를 찾는다.

    OIDC 신뢰 당사자가 인가 요청이나 OIDC 인증 요청을 시작하기 위해서 ClientID와 ClientSecret 값을 알아야 한다.

    이는 OIDC 동적 클라이언트 등록 스펙에 따른다.

    • OIDC 동적 클라이언트 등록은 OpenID 공급자에서 동적으로 OIDC 신뢰 당사자를 등록하는 메커니즘이다.

     

    OpenID 공급자 메타데이터 엔드포인트의 응답에는 registration_endpoint 파라미터가 포함되어 있다.

    이 파라미터는 클라이언트 등록을 위한 엔드포인트가 포함된다.

     

    위 두 과정이 끝나면 신뢰 당사자는 OIDC 인증 요청을 시작할 수 있다.

     


    12. 보안 API를 위한 OIDC

    결국 OAuth는 위임된 인가에 관한 것이고 OIDC는 인증에 관한 것이다.

    ID토큰을 API 인증에 사용할 수 있다.

    ID 토큰 또는 JWT를 API 서버에 전달함으로 그 유효성을 검증할 수 있다.

    댓글

Designed by Tistory.