프런트 엔드 앱의 사용자 자격 증명을 수락하도록 백 엔드 App Service를 만들고 구성한 다음 해당 자격 증명을 다운스트림 Azure 서비스에 교환하는 방법을 알아봅니다. 이렇게 하면 사용자가 프런트 엔드 App Service에 로그인하고, 자격 증명을 백 엔드 App Service에 전달한 다음, 동일한 ID로 Azure 서비스에 액세스할 수 있습니다.
이 튜토리얼에서는 다음을 배우게 됩니다:
- 다운스트림 Azure 서비스에 범위가 지정된 토큰을 제공하도록 백 엔드 인증 앱 구성
- JavaScript 코드를 사용하여 로그인한 사용자의 액세스 토큰을 다운스트림 서비스에 대한 새 토큰으로 교환합니다.
- JavaScript 코드를 사용하여 다운스트림 서비스에 액세스합니다.
필수 조건
이 자습서를 시작하기 전에 보안 JavaScript 앱에서 사용자로 Microsoft Graph에 액세스하는 이전 자습서를 완료하지만 자습서가 끝날 때 리소스를 제거하지 마세요. 이 자습서에서는 두 개의 App Services와 해당 인증 앱이 있다고 가정합니다.
이전 자습서에서는 Azure CLOUD Shell을 Azure CLI의 셸로 사용했습니다. 이 자습서에서는 이 사용을 계속합니다.
건축학
이 자습서에서는 프런트 엔드 앱에서 제공하는 사용자 자격 증명을 백 엔드 앱에 전달한 다음 Azure 서비스에 전달하는 방법을 보여 줍니다. 이 자습서에서 다운스트림 서비스는 Microsoft Graph입니다. 사용자의 자격 증명은 Microsoft Graph에서 프로필을 가져오는 데 사용됩니다.
사용자가 이 아키텍처에서 Microsoft Graph 정보를 가져오는 인증 흐름:
이전 자습서 에서는 다음을 다루었습니다.
- Active Directory를 ID 공급자로 사용하도록 구성된 프런트 엔드 App Service에 사용자를 로그인합니다.
- 프런트 엔드 App Service는 사용자의 토큰을 백 엔드 App Service에 전달합니다.
- 백 엔드 앱은 프런트 엔드가 API 요청을 만들 수 있도록 보호됩니다. 사용자의 액세스 토큰은 백엔드 API와 범위
user_impersonation에 대한 대상을 가집니다. - 백엔드 애플리케이션 등록에는 범위가 있는 Microsoft Graph가 이미 포함되어 있습니다
User.Read. 기본적으로 모든 앱 등록에 추가됩니다. - 이전 자습서의 끝에서 Graph가 연결되지 않았기 때문에 가짜 프로필이 프런트 엔드 앱으로 반환되었습니다.
이 자습서에서는 아키텍처를 확장합니다.
- 백 엔드 앱에 대한 사용자 동의 화면을 무시하도록 관리자 동의를 부여합니다.
- 프런트 엔드 앱에서 보낸 액세스 토큰을 Microsoft Graph에 필요한 권한이 있는 액세스 토큰으로 변환하도록 애플리케이션 코드를 변경합니다.
- Microsoft Graph와 같은 다운스트림 Azure 서비스의 범위를 사용하여 새 토큰에 대한 백 엔드 앱 교환 토큰 을 갖는 코드를 제공합니다.
- 백 엔드 앱이 새 토큰을 사용하여 현재 인증 사용자로 다운스트림 서비스에 액세스하도록 하는 코드를 제공합니다.
- 를 사용하여 백 엔드 앱을
az webapp up합니다. - 이 자습서의 끝부분에는 그래프가 연결되었기 때문에 실제 프로필이 프런트 엔드 앱으로 반환됩니다.
이 자습서는 다음을 수행하지 않습니다.
- 이전 자습서에서 프런트 엔드 앱을 변경합니다.
- 기본적으로 모든 인증 앱에
User.Read이 추가되므로, 백엔드 인증 앱의 범위 권한을 변경합니다.
1. 백 엔드 앱에 대한 관리자 동의 구성
이전 자습서에서는 사용자가 프런트 엔드 앱에 로그인했을 때 사용자 동의를 요청하는 팝업이 표시됩니다.
이 자습서에서는 Microsoft Graph에서 사용자 프로필을 읽기 위해, 백엔드 앱이 로그인한 사용자의 액세스 토큰을 Microsoft Graph에 필요한 권한이 포함된 새 액세스 토큰으로 바꾸어야 합니다. 사용자가 백 엔드 앱에 직접 연결되지 않으므로 동의 화면에 대화형으로 액세스할 수 없습니다. 관리자 동의를 부여하려면 Microsoft Entra ID에서 백 엔드 앱의 앱 등록을 구성하여 이 작업을 수행해야 합니다. 이는 일반적으로 Active Directory 관리자가 수행하는 설정 변경입니다.
Azure Portal을 열고 백 엔드 App Service에 대한 연구를 검색합니다.
설정 -> 인증 섹션을 찾습니다.
ID 공급자를 선택하여 인증 앱으로 이동합니다.
인증 앱에서 관리 -> API 권한을 선택합니다.
기본 디렉터리에 대한 관리자 동의 부여를 선택합니다.
팝업 창에서 예를 선택하여 동의를 확인합니다.
상태 열이 기본 디렉터리 부여됨으로 표시되는지 확인합니다. 이 설정을 사용하면 백 엔드 앱이 더 이상 로그인한 사용자에게 동의 화면을 표시할 필요가 없으며 액세스 토큰을 직접 요청할 수 있습니다. 로그인된 사용자는 앱 등록 시 생성되는 기본 범위인
User.Read범위 설정에 액세스할 수 있습니다.
2. npm 패키지 설치
이전 자습서에서는 Azure Portal에서 ID 공급자를 구성하여 유일한 인증을 제공했기 때문에 백 엔드 앱에 인증을 위한 npm 패키지가 필요하지 않았습니다. 이 자습서에서는 백 엔드 API에 대한 로그인한 사용자의 액세스 토큰을 해당 범위에서 Microsoft Graph와 액세스 토큰으로 교환해야 합니다. 이 교환은 더 이상 App Service 인증을 사용하지 않지만 Microsoft Entra ID 및 MSAL.js 직접 사용하기 때문에 두 개의 라이브러리로 완료됩니다.
- @azure/MSAL-node - 교환 토큰
- @microsoft/microsoft-graph-client - Microsoft Graph에 연결
Azure Cloud Shell을 열고 샘플 디렉터리의 백 엔드 앱으로 변경합니다.
cd js-e2e-web-app-easy-auth-app-to-app/backendAzure MSAL npm 패키지를 설치합니다.
npm install @azure/msal-nodeMicrosoft Graph npm 패키지를 설치합니다.
npm install @microsoft/microsoft-graph-client
3. Microsoft Graph 토큰에 대한 현재 토큰을 교환하는 코드 추가
이 단계를 완료하기 위한 소스 코드가 제공됩니다. 다음 단계를 사용하여 포함합니다.
./src/server.js파일을 엽니다.파일 맨 위에 있는 다음 종속성의 주석을 해제합니다.
import { getGraphProfile } from './with-graph/graph';동일한 파일에서
graphProfile변수의 주석을 제거하십시오.let graphProfile={};동일한 파일에서 Microsoft Graph에서 프로필을 가져오려면
getGraphProfile경로의 다음get-profile줄의 주석 처리를 제거하십시오.// where did the profile come from profileFromGraph=true; // get the profile from Microsoft Graph graphProfile = await getGraphProfile(accessToken); // log the profile for debugging console.log(`profile: ${JSON.stringify(graphProfile)}`);변경 내용을 저장합니다. Ctrl s + .
백 엔드 앱을 다시 배포합니다.
az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name>
4. 백 엔드 코드를 검사하여 Microsoft Graph 토큰에 대한 백 엔드 API 토큰 교환
Microsoft Graph 토큰에 대한 백 엔드 API 대상 토큰을 변경하려면 백 엔드 앱이 테넌트 ID를 찾아 MSAL.js 구성 개체의 일부로 사용해야 합니다. Microsoft를 ID 공급자로 구성한 백 엔드 앱은 테넌트 ID 및 기타 여러 필수 값이 App Service 앱 설정에 이미 있습니다.
샘플 앱에서 다음 코드가 이미 제공됩니다. 이 기능이 있는 이유와 작동 방식을 이해하여 이 동일한 기능이 필요한 빌드하는 다른 앱에 이 작업을 적용할 수 있도록 해야 합니다.
테넌트 ID를 가져오는 코드 검사
./backend/src/with-graph/auth.js파일을 엽니다.getTenantId()함수를 검토합니다.export function getTenantId() { const openIdIssuer = process.env.WEBSITE_AUTH_OPENID_ISSUER; const backendAppTenantId = openIdIssuer.replace(/https:\/\/sts\.windows\.net\/(.{1,36})\/v2\.0/gm, '$1'); return backendAppTenantId; }이 함수는 환경 변수에서 현재 테넌트 ID를
WEBSITE_AUTH_OPENID_ISSUER가져옵니다. ID는 정규 표현식을 사용하여 변수에서 추출됩니다.
MSAL.js 사용하여 코드를 검사하여 그래프 토큰 가져오기
./backend/src/with-graph/auth.js파일에서 여전히getGraphToken()함수를 검토하십시오.MSAL.js 구성 개체를 빌드하고 MSAL 구성을 사용하여 clientCredentialAuthority를 만듭니다. 대리 요청을 구성합니다. 그런 다음 acquireTokenOnBehalfOf를 사용하여 Graph 액세스 토큰에 대한 백 엔드 API 액세스 토큰을 교환합니다.
// ./backend/src/auth.js // Exchange current bearerToken for Graph API token // Env vars were set by App Service export async function getGraphToken(backEndAccessToken) { const config = { // MSAL configuration auth: { // the backend's authentication CLIENT ID clientId: process.env.WEBSITE_AUTH_CLIENT_ID, // the backend's authentication CLIENT SECRET clientSecret: process.env.MICROSOFT_PROVIDER_AUTHENTICATION_SECRET, // OAuth 2.0 authorization endpoint (v2) // should be: https://login.microsoftonline.com/BACKEND-TENANT-ID authority: `https://login.microsoftonline.com/${getTenantId()}` }, // used for debugging system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: true, logLevel: MSAL.LogLevel.Verbose, } } }; const clientCredentialAuthority = new MSAL.ConfidentialClientApplication(config); const oboRequest = { oboAssertion: backEndAccessToken, // this scope must already exist on the backend authentication app registration // and visible in resources.azure.com backend app auth config scopes: ["https://graph.microsoft.com/.default"] } // This example has App service validate token in runtime // from headers that can't be set externally // If you aren't using App service's authentication, // you must validate your access token yourself // before calling this code try { const { accessToken } = await clientCredentialAuthority.acquireTokenOnBehalfOf(oboRequest); return accessToken; } catch (error) { console.log(`getGraphToken:error.type = ${error.type} ${error.message}`); } }
5. 백 엔드 코드를 검사하여 새 토큰으로 Microsoft Graph에 액세스
프런트 엔드 애플리케이션에 로그인한 사용자로 Microsoft Graph에 액세스하기 위해 변경 내용은 다음과 같습니다.
- 필요한 범위를
User.Read사용하여 다운스트림 서비스인 Microsoft Graph에 대한 API 권한으로 Active Directory 앱 등록 구성 - 백 엔드 앱에 대한 사용자 동의 화면을 무시하도록 관리자 동의를 부여합니다.
- 프런트 엔드 앱에서 보낸 액세스 토큰을 다운스트림 서비스 Microsoft Graph에 필요한 권한이 있는 액세스 토큰으로 변환하도록 애플리케이션 코드를 변경합니다.
이제 코드에 Microsoft Graph에 대한 올바른 토큰이 있으므로 이 토큰을 사용하여 Microsoft Graph에 클라이언트를 만든 다음 사용자의 프로필을 가져옵니다.
./backend/src/graph.js을 여세요.함수에서
getGraphProfile()토큰을 가져오고 토큰에서 인증된 클라이언트를 가져오고 프로필을 가져옵니다.// import graph from "@microsoft/microsoft-graph-client"; import { getGraphToken } from "./auth.js"; // Create client from token with Graph API scope export function getAuthenticatedClient(accessToken) { const client = graph.Client.init({ authProvider: (done) => { done(null, accessToken); } }); return client; } export async function getGraphProfile(accessToken) { // exchange current backend token for token with // graph api scope const graphToken = await getGraphToken(accessToken); // use graph token to get Graph client const graphClient = getAuthenticatedClient(graphToken); // get profile of user const profile = await graphClient .api('/me') .get(); return profile; }
6. 변경 내용 테스트
브라우저에서 프런트 엔드 웹 사이트를 사용합니다. 토큰이 만료된 경우 토큰을 새로 고쳐야 할 수 있습니다.
Get user's profile를 선택합니다. 이는 전달자 토큰의 인증을 백 엔드로 전달합니다.백 엔드는 계정에 대한 실제 Microsoft Graph 프로필로 응답합니다.
7. 정리
이전 단계에서는 리소스 그룹에서 Azure 리소스를 만들었습니다.
Cloud Shell에서 다음 명령을 실행하여 리소스 그룹을 삭제합니다. 이 명령을 실행하는 데 1분 정도 걸릴 수 있습니다.
az group delete --name myAuthResourceGroup이전에 백 엔드 및 프런트 엔드 앱에 대한 섹션에서 찾아서 기록한 인증 앱의
Enable authentication and authorization를 사용합니다.프런트 엔드 및 백 엔드 앱 모두에 대한 앱 등록을 삭제합니다.
# delete app - do this for both frontend and backend client ids az ad app delete <client-id>
자주 묻는 질문
오류가 80049217발생했습니다. 무엇을 의미하나요?
이 오류는 CompactToken parsing failed with error code: 80049217 백엔드 앱 서비스가 Microsoft Graph 토큰을 반환할 수 있도록 승인되지 않았다는 것을 의미합니다. 이 오류는 앱 등록에 User.Read 사용 권한이 없어서 발생합니다.
오류가 AADSTS65001발생했습니다. 무엇을 의미하나요?
이 오류는 AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resource백 엔드 인증 앱이 관리자 동의를 위해 구성되지 않았음을 의미합니다. 오류가 백 엔드 앱의 로그에 표시되기 때문에 프런트 엔드 애플리케이션은 프런트 엔드 앱에서 프로필이 보이지 않는 이유를 사용자에게 알릴 수 없습니다.
다른 다운스트림 Azure 서비스에 사용자로 연결하려면 어떻게 해야 하나요?
이 자습서에서는 Microsoft Graph에 인증된 API 앱을 보여 줍니다. 그러나 사용자를 대신하여 모든 Azure 서비스에 액세스하기 위해 동일한 일반 단계를 적용할 수 있습니다.
- 프런트 엔드 애플리케이션은 변경되지 않습니다. 백 엔드의 인증 앱 등록 및 백 엔드 앱 소스 코드만 변경합니다.
- 사용자에게 백엔드 API에 대해 범위가 지정된 토큰을, 액세스하고자 하는 다운스트림 서비스에 대한 토큰으로 교환합니다.
- 다운스트림 서비스의 SDK에서 토큰을 사용하여 클라이언트를 만듭니다.
- 다운스트림 클라이언트를 사용하여 서비스 기능에 액세스합니다.