Microsoft ID 플랫폼 및 OAuth 2.0 리소스 소유자 암호 자격 증명

Microsoft ID 플랫폼은 OAuth 2.0 ROPC(리소스 소유자 암호 자격 증명) 권한 부여를 지원하므로 애플리케이션에서 암호를 직접 처리하여 사용자 로그인을 실행할 수 있습니다. 이 문서에서는 애플리케이션에서 프로토콜에 대해 직접 프로그래밍을 수행하는 방법을 설명합니다. 가능하다면 토큰을 획득하고 보안 웹 API를 호출하는 대신, 지원되는 MSAL(Microsoft 인증 라이브러리)을 사용하는 것이 좋습니다. MSAL을 사용하는 샘플 앱도 살펴봅니다.

Warning

Microsoft 권장 사항: ROPC 흐름을 사용하지 않는 것이 좋습니다. 대부분의 시나리오에서는 더 안전한 대체 방법을 사용하며 권장합니다. 이 흐름은 애플리케이션에서 매우 높은 신뢰 수준을 요구하며, 다른 흐름에는 없는 위험을 전달합니다. 보다 안전한 다른 흐름을 실행할 수 없는 경우에만 이 흐름을 사용해야 합니다.

Important

  • Microsoft ID 플랫폼은 개인 계정이 아닌 Microsoft Entra 테넌트 내의 ROPC 부여만 지원합니다. 이는 테넌트별 엔드포인트(https://login.microsoftonline.com/{TenantId_or_Name}) 또는 organizations 엔드포인트를 사용해야 함을 의미합니다.
  • Microsoft Entra 테넌트에 초대된 개인 계정은 ROPC 흐름을 사용할 수 없습니다.
  • 암호가 없는 계정은 ROPC로 로그인할 수 없습니다. 즉, SMS 로그인, FIDO 및 Authenticator 앱과 같은 기능이 해당 흐름에서 작동하지 않습니다. 앱 또는 사용자에게 이러한 기능이 필요한 경우 ROPC가 아닌 다른 권한 부여 유형을 사용합니다.
  • 사용자가 MFA(Multi-Factor Authentication)를 사용하여 애플리케이션에 로그인해야 하는 경우, 사용자가 차단됩니다.
  • ROPC는 하이브리드 ID 페더레이션 시나리오(예: 온-프레미스 계정을 인증하는 데 사용되는 Microsoft Entra ID 및 AD FS)에서 지원되지 않습니다. 사용자가 전체 페이지를 온-프레미스 ID 공급자로 리디렉션하는 경우 Microsoft Entra ID는 해당 ID 공급자에 대해 사용자 이름과 암호를 테스트할 수 없습니다. 그러나 통과 인증은 ROPC에서 지원됩니다.
  • 하이브리드 ID 페더레이션 시나리오의 예외는 다음과 같습니다. AllowCloudPasswordValidation이 TRUE로 설정된 홈 영역 검색 정책을 사용하면 온-프레미스 암호가 클라우드와 동기화될 때 ROPC 흐름이 페더레이션된 사용자에 대해 작동할 수 있습니다. 자세한 내용은 레거시 애플리케이션에 페더레이션된 사용자의 직접 ROPC 인증 사용을 참조하세요.
  • 선행 또는 후행 공백이 있는 암호는 ROPC 흐름에서 지원되지 않습니다.

프로토콜 다이어그램

다음 다이어그램에서는 ROPC 흐름을 보여 줍니다.

Diagram showing the resource owner password credential flow

권한 부여 요청

ROPC 흐름은 단일 요청입니다. 클라이언트 식별 및 사용자의 자격 증명을 ID 공급자에 보내고 그 대가로 토큰을 받습니다. 이렇게 하려면 먼저 클라이언트에서 사용자의 이메일 주소(UPN) 및 암호를 요청해야 합니다. 요청이 성공한 즉시 클라이언트는 메모리에서 사용자의 자격 증명을 안전하게 폐기해야 합니다. 이를 저장하면 안 됩니다.

// Line breaks and spaces are for legibility only.  This is a public client, so no secret is required.

POST {tenant}/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=user.read%20openid%20profile%20offline_access
&username=MyUsername@myTenant.com
&password=SuperS3cret
&grant_type=password
매개 변수 Condition 설명
tenant 필수 사용자를 로그인할 디렉터리 테넌트입니다. 테넌트는 GUID 또는 친숙한 이름 형식일 수 있습니다. 그러나 매개 변수는 common 또는 consumers로 설정할 수 없고 organizations로 설정할 수 있습니다.
client_id Required Microsoft Entra 관리 센터 - 앱 등록 페이지에서 앱에 할당한 애플리케이션(클라이언트) ID입니다.
grant_type Required password로 설정해야 합니다.
username Required 사용자의 전자 메일 주소입니다.
password Required 사용자의 암호입니다.
scope 권장 앱에 필요한 범위 또는 권한의 공백으로 구분된 목록입니다. 대화형 흐름에서 관리자 또는 사용자는 이러한 범위에 대해 사전에 동의해야 합니다.
client_secret 때때로 필요 앱이 퍼블릭 클라이언트인 경우, client_secret 또는 client_assertion은 포함될 수 없습니다. 앱이 기밀 클라이언트인 경우, 이는 반드시 포함되어야 합니다.
client_assertion 때때로 필요 인증서를 사용하여 생성되는 다른 형식의 client_secret입니다. 자세한 내용은 인증서 자격 증명을 참조하세요.

성공적인 인증 응답

다음 예제에서는 성공적인 토큰 응답을 보여 줍니다.

{
    "token_type": "Bearer",
    "scope": "User.Read profile openid email",
    "expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
매개 변수 서식 설명
token_type 문자열 항상 Bearer로 설정합니다.
scope 공백으로 구분된 문자열 액세스 토큰이 반환된 경우 이 매개 변수는 액세스 토큰의 유효 범위를 나열합니다.
expires_in int 포함된 액세스 토큰의 유효 시간(초)입니다.
access_token 불투명 문자열 요청된 범위에 대해 발급되었습니다.
id_token JWT 원래 scope 매개 변수에 openid 범위가 포함된 경우에 발급됩니다.
refresh_token 불투명 문자열 원래 scope 매개 변수에 offline_access가 포함된 경우에 발급됩니다.

새로 고침 토큰은 OAuth 코드 흐름 문서에 설명된 동일한 흐름을 사용하여 새 액세스 토큰과 새로 고침 토큰을 가져올 수 있습니다.

Warning

코드에서 이 예제의 토큰을 포함하여 소유하지 않은 API에 대한 토큰을 확인하거나 읽으려고 시도하지 마세요. Microsoft 서비스 토큰은 JWT로 유효성을 검사하지 않는 특수 형식을 사용할 수 있으며 소비자(Microsoft 계정) 사용자에 대해 암호화될 수도 있습니다. 토큰 읽기는 유용한 디버깅 및 학습 도구이지만 코드에서 이에 대한 종속성을 취하거나 제어하는 API용이 아닌 토큰에 대한 세부 사항을 가정하지 마세요.

오류 응답

사용자가 올바른 사용자 이름 또는 암호를 입력하지 않았거나 클라이언트가 요청된 동의를 수신하지 못한 경우 인증에 실패합니다.

오류 설명 클라이언트 작업
invalid_grant 인증에 실패했습니다. 자격 증명이 올바르지 않거나 클라이언트에 요청된 범위에 대한 동의가 없습니다. 범위에 권한이 부여되지 않으면 consent_required 오류가 반환됩니다. 이 오류를 해결하기 위해 클라이언트는 웹 보기 또는 브라우저를 사용하여 대화형 프롬프트로 사용자를 전송해야 합니다.
invalid_request 요청이 잘못 구성되었습니다. 권한 부여 유형은 /common 또는 /consumers 인증 컨텍스트에서 지원되지 않습니다. 그 대신 /organizations 또는 테넌트 ID를 사용합니다.

자세한 정보

ROPC 흐름의 예제 구현은 GitHub의 .NET 콘솔 애플리케이션 코드 샘플을 참조하세요.