이제 토큰이 있으므로 보호된 웹 API를 호출할 수 있습니다. 일반적으로 웹앱의 컨트롤러나 페이지에서 다운스트림 API를 호출합니다.
보호된 웹 API를 호출하는 과정은 선택한 언어 및 프레임워크에 따라 다릅니다.
Microsoft.Identity.Web을 사용하는 경우 API를 호출하기 위한 세 가지 사용 옵션이 있습니다.
옵션 1: SDK를 사용하여 Microsoft Graph 호출
이 시나리오에서는 코드 구성에 지정된 대로 .AddMicrosoftGraph()
을(를) Startup.cs에 포함하고 Microsoft.Identity.Web.GraphServiceClient NuGet 패키지를 추가하여 Microsoft Graph를 호출합니다. 그런 다음 컨트롤러 또는 페이지 생성자에 GraphServiceClient
를 직접 삽입하여 작업에서 사용할 수 있습니다. 다음 Razor 페이지 예에서는 로그인한 사용자의 사진이 표시됩니다.
[Authorize]
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public class IndexModel : PageModel
{
private readonly GraphServiceClient _graphServiceClient;
public IndexModel(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task OnGet()
{
var user = await _graphServiceClient.Me.GetAsync();
try
{
using (var photoStream = await _graphServiceClient.Me.Photo.Content.GetAsync())
{
byte[] photoByte = ((MemoryStream)photoStream).ToArray();
ViewData["photo"] = Convert.ToBase64String(photoByte);
}
ViewData["name"] = user.DisplayName;
}
catch (Exception)
{
ViewData["photo"] = null;
}
}
}
전체 샘플을 보려면 Microsoft Graph를 호출하는 ASP.NET Core 웹앱을 참조하세요.
옵션 2: helper 클래스를 사용하여 다운스트림 웹 API 호출
Microsoft Graph가 아닌 웹 API를 호출하려고 합니다. 이 경우에는 코드 구성에 지정된 대로 Startup.cs에 AddDownstreamApi
를 추가했으며 컨트롤러 또는 페이지 생성자에 IDownstreamApi
서비스를 직접 삽입하고 작업에 사용할 수 있습니다.
[Authorize]
[AuthorizeForScopes(ScopeKeySection = "TodoList:Scopes")]
public class TodoListController : Controller
{
private IDownstreamApi _downstreamApi;
private const string ServiceName = "TodoList";
public TodoListController(IDownstreamApi downstreamApi)
{
_downstreamApi = downstreamApi;
}
public async Task<ActionResult> Details(int id)
{
var value = await _downstreamApi.CallApiForUserAsync(
ServiceName,
options =>
{
options.RelativePath = $"me";
});
return View(value);
}
}
CallWebApiForUserAsync
에는 직접 개체를 받을 수 있도록 하는 강력한 형식의 일반적인 재정의가 있습니다. 예를 들어 다음 메서드는 웹 API에서 반환된 JSON의 강력한 형식의 표현인 Todo
인스턴스를 수신합니다.
// GET: TodoList/Details/5
public async Task<ActionResult> Details(int id)
{
var value = await _downstreamApi.CallApiForUserAsync<object, Todo>(
ServiceName,
null,
options =>
{
options.HttpMethod = HttpMethod.Get;
options.RelativePath = $"api/todolist/{id}";
});
return View(value);
}
전체 샘플을 보려면 API를 호출하는 ASP.NET Core 웹앱을 참조하세요.
옵션 3: 도우미 클래스 없이 다운스트림 웹 API 호출
IAuthorizationHeaderProvider
서비스를 사용하여 토큰을 수동으로 획득하기로 결정했으므로 이제 토큰을 사용해야 합니다. 이 경우, 다음 코드는 계속해서 웹 API를 호출하는 웹앱: 앱에 대한 토큰 획득에 표시된 코드 예입니다. 이 코드는 웹앱 컨트롤러의 작업에서 호출됩니다.
토큰을 획득한 후에는 전달자 토큰으로 사용하여 다운스트림 API를 호출합니다. 이 경우에는 Microsoft Graph입니다.
public async Task<IActionResult> Profile()
{
// Acquire the access token.
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await IAuthorizationHeaderProvider.GetAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient httpClient = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
var response = await httpClient.GetAsync($"{webOptions.GraphApiUrl}/beta/me");
if (response.StatusCode == HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
dynamic me = JsonConvert.DeserializeObject(content);
ViewData["Me"] = me;
}
return View();
}
참고 항목
동일한 원칙을 사용하여 웹 API를 호출할 수 있습니다.
대부분의 Azure 웹 API는 Microsoft Graph의 경우처럼 API 호출을 간소화하는 SDK를 제공합니다.
Microsoft.Identity.Web을 사용하는 경우 API를 호출하기 위한 세 가지 사용 옵션이 있습니다.
옵션 1: OWIN 앱에서 SDK를 사용하여 Microsoft Graph 호출
Microsoft Graph를 호출하려고 합니다. 이 시나리오에서는 코드 구성에 지정된 대로 Startup.cs에 AddMicrosoftGraph
를 추가했으며, 컨트롤러에서 GetGraphServiceClient()
확장 메서드를 사용하여 작업에 사용할 수 있도록 컨트롤러 또는 페이지 생성자에서 GraphServiceClient
를 가져올 수 있습니다. 다음 예에서는 로그인한 사용자의 사진을 표시합니다.
[Authorize]
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public class HomeController : Controller
{
public async Task GetIndex()
{
var graphServiceClient = this.GetGraphServiceClient();
var user = await graphServiceClient.Me.GetAsync();
try
{
using (var photoStream = await graphServiceClient.Me.Photo.Content.GetAsync())
{
byte[] photoByte = ((MemoryStream)photoStream).ToArray();
ViewData["photo"] = Convert.ToBase64String(photoByte);
}
ViewData["name"] = user.DisplayName;
}
catch (Exception)
{
ViewData["photo"] = null;
}
}
}
전체 샘플을 보려면 Microsoft Graph를 호출하는 ASP.NET OWIN 웹앱을 참조하세요.
옵션 2: OWIN 앱의 도우미 클래스를 사용하여 다운스트림 웹 API 호출
Microsoft Graph가 아닌 웹 API를 호출하려고 합니다. 이 경우 코드 구성에 지정된 대로 Startup.cs에 AddDownstreamApi
를 추가했으며 컨트롤러에서 GetDownstreamApi
확장 메서드를 호출하여 컨트롤러에서 IDownstreamApi
서비스를 가져올 수 있습니다.
[Authorize]
public class TodoListController : Controller
{
public async Task<ActionResult> Details(int id)
{
var downstreamApi = this.GetDownstreamApi();
var value = await downstreamApi.CallApiForUserAsync(
ServiceName,
options =>
{
options.RelativePath = $"me";
});
return View(value);
}
}
CallApiForUserAsync
에는 직접 개체를 받을 수 있도록 하는 강력한 형식의 일반적인 재정의가 있습니다. 예를 들어 다음 메서드는 웹 API에서 반환된 JSON의 강력한 형식의 표현인 Todo
인스턴스를 수신합니다.
// GET: TodoList/Details/5
public async Task<ActionResult> Details(int id)
{
var downstreamApi = this.GetDownstreamApi();
var value = await downstreamApi.CallApiForUserAsync<object, Todo>(
ServiceName,
null,
options =>
{
options.HttpMethod = HttpMethod.Get;
options.RelativePath = $"api/todolist/{id}";
});
return View(value);
}
옵션 3: OWIN 앱에서 도우미 클래스 없이 다운스트림 웹 API 호출
IAuthorizationHeaderProvider
서비스를 사용하여 인증 헤더를 획득하기로 결정했으며 이제 HttpClient 또는 HttpRequest에서 이를 사용해야 합니다. 이 경우, 다음 코드는 계속해서 웹 API를 호출하는 웹앱: 앱에 대한 토큰 획득에 표시된 코드 예입니다. 이 코드는 웹앱 컨트롤러의 작업에서 호출됩니다.
public async Task<IActionResult> Profile()
{
// Acquire the access token.
string[] scopes = new string[]{"user.read"};
var IAuthorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string authorizationHeader = await IAuthorizationHeaderProvider.GetAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient httpClient = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
var response = await httpClient.GetAsync($"{webOptions.GraphApiUrl}/beta/me");
if (response.StatusCode == HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
dynamic me = JsonConvert.DeserializeObject(content);
ViewData["Me"] = me;
}
return View();
}
private String getUserInfoFromGraph(String accessToken) throws Exception {
// Microsoft Graph user endpoint
URL url = new URL("https://graph.microsoft.com/v1.0/me");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Set the appropriate header fields in the request header.
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept", "application/json");
String response = HttpClientHelper.getResponseStringFromConn(conn);
int responseCode = conn.getResponseCode();
if(responseCode != HttpURLConnection.HTTP_OK) {
throw new IOException(response);
}
JSONObject responseObject = HttpClientHelper.processResponse(responseCode, response);
return responseObject.toString();
}
토큰을 성공적으로 쿼리한 후 코드는 axios 패키지를 사용하여 API 엔드포인트를 쿼리하고 JSON 결과를 쿼리합니다.
/**
* Attaches a given access token to a MS Graph API call
* @param endpoint: REST API endpoint to call
* @param accessToken: raw access token string
*/
async function fetch(endpoint, accessToken) {
const options = {
headers: {
Authorization: `Bearer ${accessToken}`
}
};
console.log(`request made to ${endpoint} at: ` + new Date().toString());
try {
const response = await axios.get(endpoint, options);
return await response.data;
} catch (error) {
throw new Error(error);
}
}
토큰을 성공적으로 쿼리한 후 코드는 요청 패키지를 사용하여 API 엔드포인트를 쿼리하고 JSON 결과를 쿼리합니다.
@app.route("/call_downstream_api")
def call_downstream_api():
token = auth.get_token_for_user(app_config.SCOPE)
if "error" in token:
return redirect(url_for("login"))
# Use access token to call downstream api
api_result = requests.get(
app_config.ENDPOINT,
headers={'Authorization': 'Bearer ' + token['access_token']},
timeout=30,
).json()
return render_template('display.html', result=api_result)