OAuth 2.0 클라이언트 자격 증명 부여 흐름은 웹 서비스(기밀 클라이언트)가 사용자를 가장하는 대신 자체 자격 증명을 사용하여 다른 웹 서비스를 호출할 때 인증할 수 있도록 허용합니다. RFC 6749에 명시된 권한 부여는 때때로 일명 두 다리 OAuth라고도 하며, 애플리케이션의 ID를 사용하여 웹에 호스팅된 리소스에 액세스하는 데 사용될 수 있습니다. 이 형식은 사용자와의 즉각적인 상호 작용 없이 백그라운드에서 실행되어야 하는 서버 간 상호 작용에 일반적으로 사용되며 디 먼 또는 서비스 계정이라고도 합니다.
클라이언트 자격 증명 흐름에서 권한은 관리자가 애플리케이션 자체에 직접 부여합니다. 앱이 리소스에 토큰을 제공하는 경우 리소스는 인증에 관련된 사용자가 없으므로 앱 자체에 작업을 수행할 수 있는 권한 부여를 적용합니다. 이 문서에서는 다음에 필요한 두 단계를 모두 설명합니다.
이 문서에서는 애플리케이션의 프로토콜에 대해 직접 프로그래밍하는 방법을 설명합니다. 가능하면 지원되는 Microsoft 인증 라이브러리(MSAL)를 사용하여 토큰을 획득하고 보안 웹 API를 호출하는 것이 좋습니다.
MSAL을 사용하는 샘플 앱을 참조할 수도 있습니다. 참고로, 이 플로우에서는 새로 고침 토큰이 부여되지 않습니다. client_id
와 client_secret
는 새로 고침 토큰을 얻는 데 필요하지만, 대신 액세스 토큰을 얻는 데 사용할 수 있습니다.
더 높은 수준의 보증을 위해 Microsoft ID 플랫폼을 사용하면 호출 서비스가 공유 비밀 대신 인증서 또는 페더레이션 자격 증명을 사용하여 인증할 수 있습니다. 애플리케이션의 자체 자격 증명이 사용 중이므로 이러한 자격 증명은 안전하게 유지되어야 합니다. 소스 코드에 해당 자격 증명을 게시하거나 웹 페이지에 포함하거나 널리 분산된 네이티브 애플리케이션에서 사용하지 마세요.
프로토콜 다이어그램
전체 클라이언트 자격 증명 흐름은 다음 다이어그램과 유사합니다. 이 문서의 뒷부분에 있는 각 단계를 설명합니다.
직접 권한 부여 가져오기
일반적으로 앱은 다음 두 가지 방법 중 하나로 리소스에 액세스하기 위한 직접 권한 부여를 받습니다.
이러한 두 가지 방법은 Microsoft Entra ID에서 가장 일반적이며 클라이언트 자격 증명 흐름을 수행하는 클라이언트 및 리소스에 권장됩니다. 리소스는 다른 방법으로 클라이언트에 권한을 부여하도록 선택할 수도 있습니다. 각 리소스 서버는 애플리케이션에 가장 적합한 방법을 선택할 수 있습니다.
액세스 제어 목록
리소스 공급자는 특정 수준의 액세스를 알고 부여하는 애플리케이션(클라이언트) ID 목록을 기반으로 권한 부여 검사를 적용할 수 있습니다. 리소스가 Microsoft ID 플랫폼에서 토큰을 받으면, 토큰을 디코딩하여 클라이언트의 애플리케이션 ID를 appid
및 iss
클레임에서 추출할 수 있습니다. 그런 다음, 애플리케이션을 유지 관리하는 ACL(액세스 제어 목록)과 비교합니다. ACL의 세분성 및 메서드는 리소스마다 크게 다를 수 있습니다.
일반적인 사용 사례는 ACL을 사용하여 웹 애플리케이션 또는 웹 API에 대한 테스트를 실행하는 것입니다. 웹 API는 특정 클라이언트에 대한 전체 권한의 하위 집합만 부여할 수 있습니다. API에서 엔드투엔드 테스트를 실행하려면 Microsoft ID 플랫폼에서 토큰을 획득한 다음 API로 보내는 테스트 클라이언트를 만들 수 있습니다. 그런 다음 API는 API의 전체 기능에 대한 모든 액세스 권한이 있는지 테스트 클라이언트의 애플리케이션 ID에 대한 ACL을 확인합니다. 이러한 종류의 ACL을 사용하는 경우 호출자의 appid
값뿐만 아니라 토큰 값이 신뢰할 수 있는지 iss
도 확인해야 합니다.
이러한 유형의 권한 부여는 개인 Microsoft 계정이 있는 소비자 사용자가 소유한 데이터에 액세스해야 하는 디먼 및 서비스 계정에 공통적으로 적용됩니다. 조직이 소유한 데이터의 경우 애플리케이션 권한을 통해 필요한 권한 부여를 받는 것이 좋습니다.
클레임 없이 roles
토큰 제어
이 ACL 기반 권한 부여 패턴을 사용하도록 설정하기 위해 Microsoft Entra ID는 애플리케이션에 다른 애플리케이션에 대한 토큰을 가져올 수 있는 권한을 부여할 필요가 없습니다. 따라서 클레임 없이 roles
앱 전용 토큰을 발급할 수 있습니다. API를 노출하는 애플리케이션은 토큰을 수락하기 위해 권한 검사를 구현해야 합니다.
애플리케이션에서 역할이 없는 앱 전용 액세스 토큰을 받지 않도록 하려면, 앱에 대한 할당 요구 사항이 사용 설정되어 있는지 확인합니다. 이렇게 하면 할당된 역할이 없는 사용자 및 애플리케이션이 이 애플리케이션에 대한 토큰을 가져올 수 없게 됩니다.
애플리케이션 권한
ACL을 사용하는 대신 API를 사용하여 애플리케이션 권한 집합을 노출할 수 있습니다. 이는 조직의 관리자가 애플리케이션에 부여하며 해당 조직 및 해당 직원이 소유한 데이터에 액세스하는 데만 사용할 수 있습니다. 예를 들어 Microsoft Graph는 다음을 수행할 수 있는 여러 애플리케이션 권한을 노출합니다.
- 모든 사서함에서 메일 읽기
- 모든 사서함에서 메일 읽기 및 쓰기
- 모든 사용자로 메일 보내기
- 디렉터리 데이터 읽기
Microsoft Graph가 아닌 사용자 고유의 API에서 앱 역할(애플리케이션 권한)을 사용하려면 먼저 Microsoft Entra 관리 센터의 API 앱 등록에서 앱 역할을 노출 해야 합니다. 그런 다음 클라이언트 애플리케이션의 앱 등록에서 해당 권한을 선택하여 필요한 앱 역할을 구성합니다. API의 앱 등록에서 앱 역할을 노출하지 않은 경우 Microsoft Entra 관리 센터의 클라이언트 애플리케이션 앱 등록에서 해당 API에 대한 애플리케이션 권한을 지정할 수 없습니다.
사용자와 달리 애플리케이션으로 인증하는 경우 앱이 대신 사용할 사용자가 없으므로 위임된 권한을 사용할 수 없습니다. 관리자 또는 API 소유자가 부여한 애플리케이션 권한(앱 역할이라고도 함)을 사용해야 합니다.
애플리케이션 권한에 대한 자세한 내용은 사용 권한 및 동의를 참조하세요.
권장 사항: 관리자를 앱에 로그인시키려면 앱 역할이 할당되도록 하십시오.
일반적으로 애플리케이션 권한을 사용하는 애플리케이션을 빌드하는 경우 앱에는 관리자가 앱의 권한을 승인하는 페이지 또는 보기가 필요합니다. 이 페이지는 앱의 로그인 흐름, 앱 설정의 일부 또는 전용 연결 흐름의 일부일 수 있습니다. 사용자가 회사 또는 학교 Microsoft 계정으로 로그인한 후에만 앱에서 이 연결 보기를 표시하는 것이 좋습니다.
앱에 사용자를 로그인하는 경우 사용자에게 애플리케이션 사용 권한을 승인하도록 요청하기 전에 사용자가 속한 조직을 식별할 수 있습니다. 꼭 필요한 것은 아니지만 사용자에게 보다 직관적인 환경을 만드는 데 도움이 될 수 있습니다. 사용자를 로그인하려면 Microsoft ID 플랫폼 프로토콜 자습서를 따릅니다.
디렉터리 관리자에게 사용 권한 요청
조직의 관리자에게 권한을 요청할 준비가 되면 사용자를 Microsoft ID 플랫폼 관리자 동의 엔드포인트로 리디렉션할 수 있습니다.
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&state=12345
&redirect_uri=http://localhost/myapp/permissions
전문가 팁: 브라우저에서 다음 요청을 붙여넣어 보세요.
https://login.microsoftonline.com/common/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions
매개 변수 | 조건 | 설명 |
---|---|---|
tenant |
필수 | 사용 권한을 요청하려는 디렉터리 테넌트입니다. GUID 또는 친숙한 이름 형식으로 지정할 수 있습니다. 사용자가 속한 테넌트를 모를 경우, 그들이 아무 테넌트로 로그인할 수 있도록 하려면 common 를 사용하세요. |
client_id |
필수 | 애플리케이션(클라이언트) ID로 Microsoft Entra 관리 센터 – 앱 등록 환경에서 귀하의 앱에 할당한 ID입니다. |
redirect_uri |
필수 | 리디렉션 URI는 처리할 앱에 응답을 전송하려는 위치입니다. URL로 인코딩되어야 하며 추가 경로 세그먼트가 있을 수 있다는 점을 제외하고 포털에 등록한 리디렉션 URI 중 하나와 정확히 일치해야 합니다. |
state |
권장 | 토큰 응답에도 반환되는 요청에 포함된 값입니다. 원하는 콘텐츠의 문자열일 수 있습니다. 상태는 인증 요청이 발생하기 전에 앱의 사용자 상태에 대한 정보를 인코딩하는 데 사용됩니다(예: 페이지 또는 보기). |
이 시점에서 Microsoft Entra ID는 테넌트 관리자만 로그인하여 요청을 완료할 수 있도록 합니다. 관리자에게 앱 등록 포털에서 앱에 대해 요청한 모든 직접 애플리케이션 권한을 승인하라는 메시지가 표시됩니다.
성공적인 응답
관리자가 애플리케이션에 대한 사용 권한을 승인하는 경우 성공적인 응답은 다음과 같습니다.
GET http://localhost/myapp/permissions?tenant=aaaabbbb-0000-cccc-1111-dddd2222eeee&state=state=12345&admin_consent=True
매개 변수 | 설명 |
---|---|
tenant |
애플리케이션에 요청한 권한을 GUID 형식으로 부여한 디렉터리 테넌트입니다. |
state |
토큰 응답에도 반환되는 요청에 포함된 값입니다. 원하는 콘텐츠의 문자열일 수 있습니다. 상태는 인증 요청이 발생하기 전에 앱의 사용자 상태에 대한 정보를 인코딩하는 데 사용됩니다(예: 페이지 또는 보기). |
admin_consent |
True로 설정합니다. |
오류 응답
관리자가 애플리케이션에 대한 사용 권한을 승인하지 않으면 실패한 응답은 다음과 같습니다.
GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
매개 변수 | 설명 |
---|---|
error |
오류 유형을 분류하는 데 사용할 수 있고 오류에 대응하는 데 사용할 수 있는 오류 코드 문자열입니다. |
error_description |
오류의 근본 원인을 식별하는 데 도움이 되는 특정 오류 메시지입니다. |
앱 프로비저닝 엔드포인트에서 성공적인 응답을 받은 후 앱이 요청한 직접 애플리케이션 권한을 얻게 됩니다. 이제 원하는 리소스에 대한 토큰을 요청할 수 있습니다.
토큰 가져오기
애플리케이션에 필요한 권한 부여를 획득한 후 API에 대한 액세스 토큰 획득을 계속 진행합니다. 클라이언트 자격 증명 부여를 사용하여 토큰을 가져오려면 MICROSOFT ID 플랫폼에 /token
POST 요청을 보냅니다. 몇 가지 다른 경우가 있습니다.
첫 번째 사례: 공유 암호를 사용하여 액세스 토큰 요청
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=A1bC2dE3f...&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
매개 변수 | 조건 | 설명 |
---|---|---|
tenant |
필수 | 애플리케이션이 GUID 또는 도메인 이름 형식으로 작동할 디렉터리 테넌트입니다. |
client_id |
필수 | 앱에 할당된 애플리케이션 ID입니다. 앱을 등록한 포털에서 이 정보를 찾을 수 있습니다. |
scope |
필수 | 이 요청의 scope 매개 변수에 전달되는 값은 원하는 리소스의 리소스 식별자(애플리케이션 ID URI)여야 하며 접미사가 붙 .default 습니다. 포함된 모든 범위는 단일 리소스에 대한 것이어야 합니다. 여러 리소스에 대한 범위를 포함하면 오류가 발생합니다. Microsoft Graph 예제의 경우 값은 .입니다 https://graph.microsoft.com/.default . 이 값은 Microsoft 인증 플랫폼에 앱에 대해 구성한 모든 직접 애플리케이션 권한 중 사용하려는 리소스에 연결된 권한에 대해 엔드포인트가 토큰을 발급해야 한다는 것을 알려줍니다. 범위에 대한 /.default 자세한 내용은 동의 설명서를 참조하세요. |
client_secret |
필수 | 앱 등록 포털에서 앱에 대해 생성한 클라이언트 암호입니다. 클라이언트 암호는 전송되기 전에 URL로 인코딩되어야 합니다. 대신 RFC 6749에 따라 권한 부여 헤더에 자격 증명을 제공하는 기본 인증 패턴도 지원됩니다. |
grant_type |
필수 | 반드시 client_credentials 로 설정해야 합니다. |
두 번째 사례: 인증서를 사용하여 액세스 토큰 요청
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
매개 변수 | 조건 | 설명 |
---|---|---|
tenant |
필수 | 애플리케이션이 GUID 또는 도메인 이름 형식으로 작동할 디렉터리 테넌트입니다. |
client_id |
필수 | 앱에 할당된 애플리케이션(클라이언트) ID입니다. |
scope |
필수 | 이 요청의 scope 매개 변수에 전달되는 값은 원하는 리소스의 리소스 식별자(애플리케이션 ID URI)여야 하며 접미사가 붙 .default 습니다. 포함된 모든 범위는 단일 리소스에 대한 것이어야 합니다. 여러 리소스에 대한 범위를 포함하면 오류가 발생합니다. Microsoft Graph 예제의 경우 값은 .입니다 https://graph.microsoft.com/.default . 이 값은 Microsoft 인증 플랫폼에 앱에 대해 구성한 모든 직접 애플리케이션 권한 중 사용하려는 리소스에 연결된 권한에 대해 엔드포인트가 토큰을 발급해야 한다는 것을 알려줍니다. 범위에 대한 /.default 자세한 내용은 동의 설명서를 참조하세요. |
client_assertion_type |
필수 | 값은 urn:ietf:params:oauth:client-assertion-type:jwt-bearer 로 설정해야 합니다. |
client_assertion |
필수 | 애플리케이션에 대한 자격 증명으로 등록한 인증서로 만들고 서명해야 하는 어설션(JSON 웹 토큰)입니다. 인증서 등록 방법 및 어설션 형식에 대한 자세한 내용은 인증서 자격 증명을 참조하세요. |
grant_type |
필수 | 반드시 client_credentials 로 설정해야 합니다. |
인증서 기반 요청의 매개 변수는 공유 비밀 기반 요청과 한 가지 방법으로만 다릅니다. client_secret
매개 변수가 client_assertion_type
및 client_assertion
매개 변수로 대체되는 것입니다.
세 번째 사례: 페더레이션 자격 증명을 사용하여 액세스 토큰 요청
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarity
Host: login.microsoftonline.com:443
Content-Type: application/x-www-form-urlencoded
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
매개 변수 | 조건 | 설명 |
---|---|---|
client_assertion |
필수 | 애플리케이션이 Kubernetes와 같은 Microsoft ID 플랫폼 외부의 다른 ID 공급자로부터 가져오는 어설션(JWT 또는 JSON 웹 토큰)입니다. 이 JWT의 세부 사항은 페더레이션 아이디 인증 정보로 애플리케이션에 등록되어야 합니다. 워크로드 ID 페더레이션에 대해 읽어 다른 ID 공급자에서 생성된 어설션을 설정 및 사용하는 방법을 알아봅니다. |
요청의 모든 항목은 인증서 기반 흐름과 동일하며, 소스의 중요한 예외는 client_assertion
예외입니다. 이 흐름에서 애플리케이션은 JWT 어설션 자체를 만들지 않습니다. 대신 앱은 다른 ID 공급자가 만든 JWT를 사용합니다. 이를 워크로드 ID 페더레이션이라고 하며, 다른 ID 플랫폼의 앱 ID를 사용하여 Microsoft ID 플랫폼 내에서 토큰을 획득합니다. 이는 Azure 외부에서 컴퓨팅을 호스팅하지만 Microsoft ID 플랫폼으로 보호되는 API에 액세스하는 것과 같은 클라우드 간 시나리오에 가장 적합합니다. 다른 ID 공급자가 만든 JWT의 필수 형식에 대한 자세한 내용은 어설션 형식을 참조하세요.
성공적인 응답
모든 메서드의 성공적인 응답은 다음과 같습니다.
{
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
매개 변수 | 설명 |
---|---|
access_token |
요청된 액세스 토큰입니다. 앱은 이 토큰을 사용하여 웹 API와 같은 보안 리소스에 인증할 수 있습니다. |
token_type |
토큰 형식 값을 나타냅니다. Microsoft ID 플랫폼에서 지원하는 유일한 형식은 .입니다 bearer . |
expires_in |
액세스 토큰이 유효한 시간(초)입니다. |
경고
코드에서 이 예제의 토큰을 포함하여 소유하지 않은 API에 대한 토큰을 확인하거나 읽으려고 시도하지 마세요. Microsoft 서비스의 토큰은 JWT로 유효성을 검사하지 않는 특수 형식을 사용할 수 있으며 소비자(Microsoft 계정) 사용자에 대해 암호화될 수도 있습니다. 토큰 읽기는 유용한 디버깅 및 학습 도구이지만 코드에서 이에 대한 종속성을 취하거나 제어하는 API용이 아닌 토큰에 대한 세부 사항을 가정하지 마세요.
오류 응답
오류 응답(400 잘못된 요청)은 다음과 같습니다.
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
"error_codes": [
70011
],
"timestamp": "YYYY-MM-DD HH:MM:SSZ",
"trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
"correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
매개 변수 | 설명 |
---|---|
error |
발생하는 오류 유형을 분류하고 오류에 대응하는 데 사용할 수 있는 오류 코드 문자열입니다. |
error_description |
인증 오류의 근본 원인을 식별하는 데 도움이 될 수 있는 특정 오류 메시지입니다. |
error_codes |
진단에 도움이 될 수 있는 STS 관련 오류 코드 목록입니다. |
timestamp |
오류가 발생한 시간입니다. |
trace_id |
진단에 도움이 되는 요청에 대한 고유 식별자입니다. |
correlation_id |
구성 요소 간 진단을 돕기 위한 요청에 대한 고유 식별자입니다. |
토큰 사용
이제 토큰을 획득했으므로 토큰을 사용하여 리소스에 대한 요청을 만듭니다. 토큰이 만료되면 엔드포인트에 대한 요청을 반복하여 /token
새 액세스 토큰을 획득합니다.
GET /v1.0/users HTTP/1.1
Host: graph.microsoft.com:443
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...
터미널에서 다음 명령을 시도하여 토큰을 사용자 고유의 토큰으로 바꾸세요.
curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG..." 'https://graph.microsoft.com/v1.0/users'
코드 샘플 및 기타 설명서
Microsoft 인증 라이브러리에서 클라이언트 자격 증명 개요 설명서를 읽습니다.
예시 | 플랫폼 | 설명 |
---|---|---|
액티브 디렉토리 닷넷코어 데몬 v2 | .NET 6.0 이상 | 사용자를 대신하여 애플리케이션의 ID를 사용하여 Microsoft Graph를 쿼리하는 테넌트 사용자를 표시하는 ASP.NET Core 애플리케이션입니다. 또한 이 샘플에서는 인증에 인증서를 사용하는 변형을 보여 줍니다. |
액티브 디렉토리 닷넷 데몬 v2 | ASP.NET MVC | 사용자를 대신하여 애플리케이션의 ID를 사용하여 Microsoft Graph의 데이터를 동기화하는 웹 애플리케이션입니다. |
ms-identity-javascript-nodejs-console | Node.js 콘솔 | 애플리케이션의 ID를 사용하여 Microsoft Graph를 쿼리하여 테넌트 사용자를 표시하는 Node.js 애플리케이션 |