클라이언트 애플리케이션 개체를 빌드한 후 이 개체를 사용하여 웹 API를 호출하는 데 사용할 수 있는 토큰을 획득합니다.
Microsoft.Identity.Web은 Microsoft Graph 또는 다운스트림 웹 API를 호출하기 위한 편리한 서비스를 제공하는 확장 메서드를 추가합니다. 해당 메서드는 웹 API를 호출하는 웹앱: API 호출에 자세히 설명되어 있습니다. 이러한 도우미 메서드를 사용하면 토큰을 수동으로 가져올 필요가 없습니다.
그러나 토큰을 수동으로 가져오려는 경우 다음 코드는 home 컨트롤러에서 Microsoft.Identity.Web을 사용하여 이 작업을 수행하는 예를 보여 줍니다. 이 코드는 Microsoft Graph SDK 대신 REST API를 사용하여 Microsoft Graph를 호출합니다. 일반적으로 토큰을 가져올 필요는 없으며 요청에 추가할 인증 헤더를 빌드해야 합니다. 인증 헤더를 가져오려면 컨트롤러 생성자(또는 Blazor를 사용하는 경우 페이지 생성자)에서 종속성 삽입을 통해 IAuthorizationHeaderProvider
서비스를 삽입하고 이를 컨트롤러 작업에서 사용합니다. 이 인터페이스에는 프로토콜(전달자, Pop 등)과 토큰이 포함된 문자열을 생성하는 메서드가 있습니다. 사용자를 대신하여 API를 호출하기 위한 인증 헤더를 가져오려면 (CreateAuthorizationHeaderForUserAsync
)를 사용합니다. 애플리케이션 자체를 대신하여 다운스트림 API를 호출하기 위한 인증 헤더를 가져오려면 디먼 시나리오에서 (CreateAuthorizationHeaderForAppAsync
)를 사용합니다.
컨트롤러 메서드는 인증된 호출만 웹 API를 사용할 수 있도록 하는 [Authorize]
특성에 의해 보호됩니다.
[Authorize]
public class MyApiController : Controller
{
/// <summary>
/// The web API will accept only tokens 1) for users, 2) that have the `access_as_user` scope for
/// this API.
/// </summary>
static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" };
static readonly string[] scopesToAccessDownstreamApi = new string[] { "api://MyTodolistService/access_as_user" };
readonly IAuthorizationHeaderProvider authorizationHeaderProvider;
public MyApiController(IAuthorizationHeaderProvider authorizationHeaderProvider)
{
this.authorizationHeaderProvider = authorizationHeaderProvider;
}
[RequiredScopes(Scopes = scopesToAccessDownstreamApi)]
public IActionResult Index()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
return await callTodoListService(authorizationHeader);
}
}
callTodoListService
메서드에 대한 자세한 내용은 웹 API를 호출하는 웹 API: API 호출을 참조하세요.
ASP.NET 코드는 ASP.NET Core에서 살펴본 코드와 비슷합니다.
- [Authorize] 특성으로 보호되는 컨트롤러 작업은 컨트롤러
ClaimsPrincipal
멤버의 테넌트 ID와 사용자 ID를 추출합니다. (ASP.NET은 HttpContext.User
를 사용합니다.) Microsoft.Identity.Web.OWIN은 Microsoft Graph 또는 다운스트림 웹 API를 호출하거나 인증 헤더 또는 토큰을 가져오기 위한 편의 서비스를 제공하는 확장 메서드를 컨트롤러에 추가합니다. API를 직접 호출하는 데 사용되는 메서드는 웹 API를 호출하는 웹앱: API 호출에 자세히 설명되어 있습니다. 이러한 도우미 메서드를 사용하면 토큰을 수동으로 가져올 필요가 없습니다.
그러나 수동으로 토큰을 획득하거나 인증 헤더를 빌드하려는 경우 다음 코드는 컨트롤러에서 Microsoft.Identity.Web을 사용하여 이를 수행하는 방법을 보여 줍니다. Microsoft Graph SDK 대신 REST API를 사용하여 API(Microsoft Graph)를 호출합니다.
인증 헤더를 가져오려면 확장 메서드 GetAuthorizationHeaderProvider
를 사용하여 컨트롤러에서 IAuthorizationHeaderProvider
서비스를 가져옵니다. 사용자를 대신하여 API를 호출하기 위한 인증 헤더를 가져오려면 (CreateAuthorizationHeaderForUserAsync
)를 사용합니다. 애플리케이션 자체를 대신하여 다운스트림 API를 호출하기 위한 인증 헤더를 가져오려면 디먼 시나리오에서(CreateAuthorizationHeaderForAppAsync
)를 사용합니다.
컨트롤러 메서드는 인증된 사용자만 웹앱을 사용할 수 있도록 하는 [Authorize]
특성에 의해 보호됩니다.
다음 코드 조각은 Microsoft Graph를 REST API로 호출하기 위한 인증 헤더를 가져오는 HomeController
의 작업을 보여 줍니다.
[Authorize]
public class MyApiController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
string json = await client.GetStringAsync(url);
}
}
다음 코드 조각은 Microsoft Graph를 REST API로 호출하기 위한 액세스 토큰을 가져오는 MyApiController
의 작업을 보여 줍니다.
[Authorize]
public class HomeController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
ITokenAcquirer tokenAcquirer = TokenAcquirerFactory.GetDefaultInstance().GetTokenAcquirer();
string[] scopes = new string[]{"user.read"};
string token = await await tokenAcquirer.GetTokenForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
string json = await client.GetStringAsync(url);
}
}
다음은 API 컨트롤러의 작업에서 호출되는 코드의 예입니다. 이 코드는 다운스트림 API - Microsoft Graph를 호출합니다.
@RestController
public class ApiController {
@Autowired
MsalAuthHelper msalAuthHelper;
@RequestMapping("/graphMeApi")
public String graphMeApi() throws MalformedURLException {
String oboAccessToken = msalAuthHelper.getOboToken("https://graph.microsoft.com/.default");
return callMicrosoftGraphMeEndpoint(oboAccessToken);
}
}
Python web API를 사용하려면 미들웨어를 사용하여 클라이언트에서 받은 전달자 토큰의 유효성을 검사해야 합니다. 그런 다음, 웹 API는 acquire_token_on_behalf_of
메서드를 호출하여 MSAL Python 라이브러리를 사용하는 다운스트림 API에 대한 액세스 토큰을 가져올 수 있습니다.
다음은 acquire_token_on_behalf_of
메서드와 Flask 프레임워크를 사용하여 액세스 토큰을 획득하는 코드의 예입니다. 다운스트림 API인 Azure 관리 구독 엔드포인트를 호출합니다.
def get(self):
_scopes = ["https://management.azure.com/user_impersonation"]
_azure_management_subscriptions_uri = "https://management.azure.com/subscriptions?api-version=2020-01-01"
current_access_token = request.headers.get("Authorization", None)
#This example only uses the default memory token cache and should not be used for production
msal_client = msal.ConfidentialClientApplication(
client_id=os.environ.get("CLIENT_ID"),
authority=os.environ.get("AUTHORITY"),
client_credential=os.environ.get("CLIENT_SECRET"))
#acquire token on behalf of the user that called this API
arm_resource_access_token = msal_client.acquire_token_on_behalf_of(
user_assertion=current_access_token.split(' ')[1],
scopes=_scopes
)
headers = {'Authorization': arm_resource_access_token['token_type'] + ' ' + arm_resource_access_token['access_token']}
subscriptions_list = req.get(_azure_management_subscriptions_uri), headers=headers).json()
return jsonify(subscriptions_list)
(고급) 백그라운드 앱, API, 서비스에서 로그인한 사용자의 토큰 캐시에 액세스
MSAL의 토큰 캐시 구현을 사용하면 백그라운드 앱, API 및 서비스에서 액세스 토큰 캐시를 사용하여 부재 중에도 사용자를 대신하여 계속 작업할 수 있습니다. 이렇게 하면 사용자가 프런트 엔드 웹앱을 종료한 후에도 백그라운드 앱 및 서비스가 사용자를 대신하여 계속 작업해야 하는 경우에 특히 유용합니다.
오늘날 대부분의 백그라운드 프로세스는 사용자의 데이터를 인증하거나 재인증하기 위해 사용자의 데이터를 사용하지 않고 작업해야 하는 경우 애플리케이션 권한을 사용합니다. 애플리케이션 권한에는 권한 상승이 필요한 관리자 동의가 필요한 경우가 많기 때문에 개발자가 해당 앱에 대해 사용자가 원래 동의한 권한 이상의 권한을 얻지 않으려는 경우에 불필요한 마찰이 발생합니다.
GitHub의 이 코드 샘플은 백그라운드 앱에서 MSAL의 토큰 캐시에 액세스하여 이러한 불필요한 마찰을 방지하는 방법을 보여줍니다.
백그라운드 앱, API 및 서비스에서 로그인한 사용자의 토큰 캐시에 액세스