Share via


Azure Active Directory B2C 사용자 지정 정책을 사용하여 REST API 호출

Azure AD B2C(Azure Active Directory B2C) 사용자 지정 정책을 사용하면 Azure AD B2C 외부에서 구현하는 애플리케이션 로직과 상호 작용할 수 있습니다. 이렇게 하려면 엔드포인트에 대한 HTTP 호출을 만듭니다. Azure AD B2C 사용자 지정 정책은 이러한 목적을 위해 RESTful 기술 프로필을 제공합니다. 이 기능을 사용하여 Azure AD B2C 사용자 지정 정책 내에서 사용할 수 없는 기능을 구현할 수 있습니다.

이 문서에서는 다음 방법을 설명합니다.

  • RESTful 서비스로 사용할 샘플 Node.js 앱을 만들고 배포합니다.

  • RESTful 기술 프로필을 사용하여 Node.js RESTful 서비스에 대한 HTTP 호출을 만듭니다.

  • RESTful 서비스가 사용자 지정 정책에 반환하는 오류를 처리하거나 보고합니다.

시나리오 개요

Azure AD B2C 사용자 지정 정책을 사용하여 사용자 경험에서 분기 만들기에서 개인 계정을 선택한 사용자는 계속 진행하려면 유효한 초대 액세스 코드를 제공해야 합니다. 정적 액세스 코드를 사용하지만 실제 앱은 이 방식으로 작동하지 않습니다. 액세스 코드를 발급하는 서비스가 사용자 지정 정책 외부에 있는 경우 해당 서비스를 호출하고 유효성 검사를 위해 사용자가 입력한 액세스 코드를 전달해야 합니다. 액세스 코드가 유효한 경우 서비스는 HTTP 200 OK 응답을 반환하고 Azure AD B2C는 JWT 토큰을 발급합니다. 그렇지 않으면 서비스가 HTTP 4xx 응답을 반환하고 사용자는 액세스 코드를 다시 입력해야 합니다.

A flowchart of calling a R E S T A P I.

필수 조건

참고 항목

이 문서는 Azure Active Directory B2C 방법 가이드 시리즈에서 사용자 고유의 사용자 지정 정책 만들기 및 실행의 일부입니다. 이 시리즈는 첫 번째 문서부터 시작하는 것이 좋습니다.

1단계 - Node.js 앱 만들기 및 배포

외부 앱 역할을 하는 앱을 배포해야 합니다. 그러면 사용자 지정 정책이 이 앱에 대한 HTTP 호출을 수행합니다.

1.1단계 - Node.js 앱 만들기

  1. access-code-app과 같은 노드 애플리케이션을 호스팅할 폴더를 만듭니다.

  2. 터미널에서 디렉터리를 cd access-code-app과 같은 노드 앱 폴더로 변경하고 npm init -y를 실행합니다. 이 명령은 Node.js 프로젝트에 대한 기본 package.json 파일을 만듭니다.

  3. 터미널에서 npm install express body-parser를 실행합니다. 이 명령은 Express 프레임워크와 body-parser 패키지를 설치합니다.

  4. 프로젝트에서 index.js 파일을 만듭니다.

  5. VS Code에서 index.js 파일을 연 후 다음 코드를 추가합니다.

        const express = require('express');
        let bodyParser = require('body-parser')
        //Create an express instance
        const app = express();
    
        app.use( bodyParser.json() );       // to support JSON-encoded bodies
        app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
          extended: true
        }));
    
    
        app.post('/validate-accesscode', (req, res) => {
            let accessCode = '88888';
            if(accessCode == req.body.accessCode){
                res.status(200).send();
            }else{
                let errorResponse = {
                    "version" :"1.0",
                    "status" : 409,
                    "code" : "errorCode",
                    "requestId": "requestId",
                    "userMessage" : "The access code you entered is incorrect. Please try again.",
                    "developerMessage" : `The provided code ${req.body.accessCode} does not match the expected code for user.`,
                    "moreInfo" :"https://docs.microsoft.com/en-us/azure/active-directory-b2c/string-transformations"
                };
                res.status(409).send(errorResponse);                
            }
        });
    
        app.listen(80, () => {
            console.log(`Access code service listening on port !` + 80);
        });
    

    사용자가 잘못된 액세스 코드를 제출하면 REST API에서 직접 오류를 반환할 수 있음을 관찰할 수 있습니다. 사용자 지정 정책을 사용하면 errorResponse 변수에 표시된 형식의 응답 JSON 본문과 함께 400(잘못된 요청) 또는 409(충돌) 응답 상태 코드와 같은 HTTP 4xx 오류 메시지를 반환할 수 있습니다. 앱의 accessCode 원본은 데이터베이스에서 읽을 수 있습니다. 유효성 검사 오류 메시지 반환에 대해 자세히 알아봅니다.

  6. 앱이 예상대로 작동하는지 테스트하려면 다음 단계를 따릅니다.

    1. 터미널에서 node index.js 명령을 실행하여 앱 서버를 시작합니다.
    2. 이 예제에 나온 것과 유사한 POST 요청을 만들려면 Microsoft PowerShell 또는 Postman과 같은 HTTP 클라이언트를 사용할 수 있습니다.
        POST http://localhost/validate-accesscode HTTP/1.1
        Host: localhost
        Content-Type: application/x-www-form-urlencoded
    
        accessCode=user-code-code
    

    user-code-code를 사용자가 입력한 액세스 코드(예: 54321)로 바꿉니다. PowerShell을 사용하는 경우 다음 스크립트를 실행합니다.

        $accessCode="54321"
        $endpoint="http://localhost/validate-accesscode"
        $body=$accessCode
        $response=Invoke-RestMethod -Method Post -Uri $endpoint -Body $body
        echo $response
    

    잘못된 액세스 코드를 사용하는 경우 응답은 다음 JSON 코드 조각과 유사합니다.

        {
            "version": "1.0",
            "status": 409,
            "code": "errorCode",
            "requestId": "requestId",
            "userMessage": "The access code you entered is incorrect. Please try again.",
            "developerMessage": "The provided code 54321 does not match the expected code for user.",
            "moreInfo": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/string-transformations"
        }
    

REST 서비스는 HTTP 4xx 상태 코드를 반환할 수 있지만 JSON 응답에서 status 값은 409여야 합니다.

이제 Node.js 앱을 배포할 준비가 되었습니다.

1.2단계 - Azure App Service에서 Node.js 앱 배포

사용자 지정 정책이 Node.js 앱에 도달하려면 도달 가능해야 하므로 배포해야 합니다. 이 문서에서는 Azure App Service를 사용하여 앱을 배포하지만 대체 호스팅 방식을 사용합니다.

Node.js 앱을 Azure에 배포하려면 Azure에 앱 배포의 단계를 따릅니다. 앱의 이름에는 custompolicyapi와 같이 설명이 포함된 이름을 사용합니다. 따라서:

  • 앱 URL은 https://custompolicyapi.azurewebsites.net과 유사합니다.

  • 서비스 엔드포인트는 https://custompolicyapi.azurewebsites.net/validate-accesscode와 유사합니다.

Microsoft PowerShell 또는 Postman과 같은 HTTP 클라이언트를 사용하여 배포한 앱을 테스트할 수 있습니다. 이번에는 https://custompolicyapi.azurewebsites.net/validate-accesscode URL을 엔드포인트로 사용합니다.

2단계 - REST API 호출

이제 앱이 실행 중이므로 사용자 지정 정책에서 HTTP 호출을 수행해야 합니다. Azure AD B2C 사용자 지정 정책은 외부 서비스를 호출하는 데 사용하는 RESTful 기술 프로필을 제공합니다.

2.1단계 - RESTful 기술 프로필 정의

ContosoCustomPolicy.XML 파일에서 ClaimsProviders 섹션을 찾고 다음 코드를 사용하여 새 RESTful 기술 프로필을 정의합니다.

    <!--<ClaimsProviders>-->
        <ClaimsProvider>
            <DisplayName>HTTP Request Technical Profiles</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="ValidateAccessCodeViaHttp">
                    <DisplayName>Check that the user has entered a valid access code by using Claims Transformations</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <Item Key="ServiceUrl">https://custompolicyapi.azurewebsites.net/validate-accesscode</Item>
                        <Item Key="SendClaimsIn">Body</Item>
                        <Item Key="AuthenticationType">None</Item>
                        <Item Key="AllowInsecureAuthInProduction">true</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="accessCode" PartnerClaimType="accessCode" />
                    </InputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    <!--</ClaimsProviders>-->

프로토콜에서 RestfulProvider를 사용하도록 기술 프로필을 구성한 것을 볼 수 있습니다. 메타데이터 섹션에서 다음 정보를 관찰할 수도 있습니다.

  • ServiceUrl은 API 엔드포인트를 나타냅니다. 해당 값은 https://custompolicyapi.azurewebsites.net/validate-accesscode입니다. 대체 방법을 사용하여 Node.js 앱을 배포한 경우 엔드포인트 값을 업데이트해야 합니다.

  • SendClaimsIn은 입력 클레임이 RESTful 클레임 공급자에게 전송되는 방법을 지정합니다. 가능한 값은 Body (default), Form, Header, Url 또는 QueryString입니다. 이 문서에서와 같이 Body를 사용할 때 POST HTTP 동사를 호출하고 요청 본문에서 키, 값 쌍으로 형식이 지정된 경우 API에 보내는 데이터를 호출합니다. GET HTTP 동사를 호출하고 데이터를 쿼리 문자열로 전달하는 방법에 대해 알아봅니다.

  • AuthenticationType은 RESTful 클레임 공급자가 수행하는 인증 형식을 지정합니다. RESTful 클레임 공급자는 보호되지 않는 엔드포인트를 호출하므로 AuthenticationType없음으로 설정합니다. 인증 형식을 Bearer로 설정하는 경우 액세스 토큰의 스토리지를 지정하는 CryptographicKeys 요소를 추가해야 합니다. RESTful 클레임 공급자가 지원하는 인증 형식에 대해 자세히 알아봅니다.

  • InputClaimPartnerClaimType 특성은 API에서 데이터를 받는 방법을 지정합니다.

2.2단계 - 유효성 검사 기술 프로필 업데이트

Azure AD B2C 사용자 지정 정책을 사용하여 사용자 경험에서 분기 만들기에서 클레임 변환을 사용하여 accessCode의 유효성을 검사했습니다. 이 문서에서는 외부 서비스에 대한 HTTP 호출을 수행하여 accessCode의 유효성을 검사합니다. 따라서 새 방식을 반영하도록 사용자 지정 정책을 업데이트해야 합니다.

AccessCodeInputCollector 기술 프로필을 찾고 ValidationTechnicalProfile 요소의 ReferenceIdValidateAccessCodeViaHttp로 업데이트합니다.

원본:

    <ValidationTechnicalProfile ReferenceId="CheckAccessCodeViaClaimsTransformationChecker"/>

다음과 같이 변경합니다.

    <ValidationTechnicalProfile ReferenceId="ValidateAccessCodeViaHttp"/>

이 시점에서 IdCheckAccessCodeViaClaimsTransformationChecker가 포함된 기술 프로필은 필요하지 않으며 제거할 수 있습니다.

3단계 - 사용자 지정 정책 파일 업로드

Node.js 앱이 실행 중인지 확인한 다음 사용자 지정 정책 파일 업로드의 단계에 따라 정책 파일을 업로드합니다. 이미 포털에 있는 파일과 이름이 같은 파일을 업로드하면 사용자 지정 정책이 이미 있는 경우 덮어쓰기를 선택해야 합니다.

4단계 - 사용자 지정 정책 테스트

사용자 지정 정책을 테스트하려면 사용자 지정 정책 테스트의 단계를 따릅니다.

  1. 계정 유형으로 개인 계정을 선택합니다.
  2. 필요에 따라 나머지 세부 정보를 입력한 다음, 계속을 선택합니다. 새 화면이 표시됩니다.
  3. 액세스 코드88888을 입력한 다음, 계속을 선택합니다. 정책 실행이 완료되면 https://jwt.ms로 리디렉션되고 디코딩된 JWT 토큰이 표시됩니다. 절차를 반복하고 88888이 아닌 다른 액세스 코드를 입력하면 다음과 같은 오류가 표시됩니다. 입력한 액세스 코드가 올바르지 않습니다. 나중에 다시 시도하세요.

5단계 - 디버그 모드 사용

개발 중에 developerMessagemoreInfo와 같이 API에서 보낸 자세한 오류를 볼 수 있습니다. 이 경우 RESTful 기술 공급자에서 디버그 모드를 사용하도록 설정해야 합니다.

  1. ValidateAccessCodeViaHttp 기술 공급자를 찾고 기술 공급자의 metadata에 다음 항목을 추가합니다.

        <Item Key="DebugMode">true</Item>
    
  2. 변경 내용을 저장하고 정책 파일을 업로드합니다.

  3. 사용자 지정 정책 테스트. 액세스 코드를 잘못 입력했는지 확인합니다. 이 스크린샷에 표시된 것과 유사한 오류가 표시됩니다.

    A screenshot error when you enable debug mode.

복잡한 요청 JSON 페이로드 처리

호출하는 REST API에서 복잡한 JSON 페이로드를 보내야 하는 경우 GenerateJson JSON 클레임 변환을 사용하여 페이로드를 만들 수 있습니다. 페이로드를 생성하면 JSON 페이로드가 포함된 클레임의 이름에 ClaimUsedForRequestPayload 메타데이터 사용 옵션을 사용할 수 있습니다.

예를 들어, 다음 클레임 변환을 사용하여 JSON 페이로드를 생성합니다.

    <ClaimsTransformation Id="GenerateRequestBodyClaimsTransformation" TransformationMethod="GenerateJson">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="customerEntity.email" />
            <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="customerEntity.userObjectId" />
            <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="customerEntity.firstName" />
            <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="customerEntity.lastName" />
            <InputClaim ClaimTypeReferenceId="accessCode" TransformationClaimType="customerEntity.accessCode" />
        </InputClaims>
        <InputParameters>
            <InputParameter Id="customerEntity.role.name" DataType="string" Value="Administrator" />
            <InputParameter Id="customerEntity.role.id" DataType="long" Value="1" />
        </InputParameters>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="requestBodyPayload" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>

ClaimsTransformation은 다음 JSON 개체를 생성합니다.

{
   "customerEntity":{
      "email":"john.s@contoso.com",
      "userObjectId":"01234567-89ab-cdef-0123-456789abcdef",
      "firstName":"John",
      "lastName":"Smith",
      "accessCode":"88888",
      "role":{
         "name":"Administrator",
         "id": 1
      }
   }
}

그런 다음 아래와 같이 RESTful 기술 공급자의 Metadata, InputClaimsTransformationsInputClaims를 업데이트합니다.

    <Metadata>
        <Item Key="ClaimUsedForRequestPayload">requestBodyPayload</Item>
        <!--Other Metadata items -->
    </Metadata>
    
    <!--Execute your InputClaimsTransformations to generate your request Payload-->
    <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateRequestBodyClaimsTransformation" />
    </InputClaimsTransformations>
    
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="requestBodyPayload" />
    </InputClaims>

REST API에서 데이터 수신

REST API가 정책에 클레임으로 포함하려는 데이터를 반환하는 경우 RESTful 기술 프로필의 OutputClaims 요소에 클레임을 지정하여 데이터를 받을 수 있습니다. 정책에 정의된 클레임의 이름이 REST API에 정의된 이름과 다른 경우 PartnerClaimType 특성을 사용하여 이러한 이름을 매핑해야 합니다.

데이터 수신의 단계에서 사용자 지정 정책에서 예상하는 데이터의 형식을 지정하는 방법, null 값을 처리하는 방법 및 API의 중첩된 JSON 본문을 REST에서 구문 분석하는 방법을 알아봅니다.

다음 단계

다음으로 알아봅니다.