이제 토큰이 있으므로 보호된 웹 API를 호출할 수 있습니다.
MSAL.NET의 AuthenticationResult 속성
토큰을 획득하는 메서드는 AuthenticationResult
를 반환합니다. 비동기 메서드의 경우 Task<AuthenticationResult>
가 반환됩니다.
MSAL.NET에서 AuthenticationResult
는 다음을 노출합니다.
- 웹 API가 리소스에 액세스하는 데 사용되는
AccessToken
. 이 매개 변수는 일반적으로 Base-64로 인코딩된 JWT인 문자열입니다. 클라이언트는 액세스 토큰 내부를 보지 않아야 합니다. 형식은 안정적 상태 유지가 보장되지 않으며 리소스에 대해 암호화할 수 있습니다. 클라이언트의 액세스 토큰 콘텐츠에 따른 코드 작성은 사용자는 오류 및 클라이언트 논리 나누기의 가장 큰 원인 중 하나입니다. 자세한 내용은 액세스 토큰을 참조하세요.
- 사용자에 대한
IdToken
. 이 매개 변수는 인코딩된 JWT입니다. 자세한 내용은 ID 토큰을 참조하세요.
ExpiresOn
은 토큰이 만료되는 날짜와 시간을 알려줍니다.
TenantId
는 사용자가 발견된 테넌트를 포함합니다. Microsoft Entra B2B 시나리오의 게스트 사용자의 경우 테넌트 ID는 고유 테넌트가 아니라 게스트 테넌트입니다.
사용자에 대해 토큰이 전달될 때 AuthenticationResult
에는 이 사용자에 대한 정보도 포함됩니다. 애플리케이션에 대한 토큰이 사용자의 개입이 없이 요청되는 기밀 클라이언트 흐름의 경우 이 사용자 정보는 null입니다.
- 토큰이 발급된
Scopes
.
- 사용자에 대한 고유한 ID.
IAccount
MSAL.NET은 IAccount
인터페이스를 통해 계정의 개념을 정의합니다. 이러한 호환성이 손상되는 변경은 올바른 의미 체계를 제공합니다. 동일한 사용자는 서로 다른 Microsoft Entra 디렉터리에 여러 계정을 가질 수 있습니다. 또한 MSAL.NET은 홈 계정 정보가 제공되므로 게스트 시나리오의 경우 더 나은 정보를 제공합니다.
다음 다이어그램에서는 IAccount
인터페이스의 구조를 보여줍니다.
AccountId
클래스는 다음 표에 나와 있는 속성을 사용하여 특정 테넌트의 계정을 식별합니다.
속성 |
설명 |
TenantId |
계정이 있는 테넌트의 ID인 GUID에 대한 문자열 표현입니다. |
ObjectId |
테넌트에 계정을 소유하고 있는 사용자의 ID인 GUID에 대한 문자열 표현입니다. |
Identifier |
계정의 고유 식별자입니다. Identifier 는 ObjectId 와 TenantId 를 쉼표로 구분하여 연결한 것입니다. Base 64로 인코딩되지 않습니다. |
IAccount
인터페이스는 단일 계정에 대한 정보를 나타냅니다. 동일한 사용자가 다른 테넌트에 있을 수 있습니다. 즉, 사용자가 여러 계정을 가질 수 있습니다. 다음 표에 해당 멤버가 나와 있습니다.
속성 |
설명 |
Username |
UPN(UserPrincipalName) 형식의 표시 가능한 값을 포함하는 문자열(예: john.doe@contoso.com). 이 문자열은 null이 아닌 HomeAccountId 및 HomeAccountId.Identifier와 달리 null일 수 있습니다. 이 속성은 이전 버전의 MSAL.NET에서 IUser 의 DisplayableId 속성을 대체합니다. |
Environment |
이 계정의 ID 공급자를 포함하는 문자열(예: login.microsoftonline.com ). 이 속성은 IUser 의 IdentityProvider 속성을 대체합니다. 단, IdentityProvider 는 클라우드 환경 외에 테넌트에 대한 정보도 가지고 있습니다. 여기서 값은 호스트일 뿐입니다. |
HomeAccountId |
사용자에 대한 홈 계정의 계정 ID. 이 속성은 Microsoft Entra 테넌트 전체에서 사용자를 고유하게 식별합니다. |
토큰을 사용하여 보호된 API 호출
MSAL이 result
에 AuthenticationResult
를 반환한 후 HTTP 인증 헤더에 이를 추가한 다음, 보호되는 웹 API에 액세스하기 위한 호출을 합니다.
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
...
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
PublicClientApplication pca = PublicClientApplication.builder(clientId)
.authority(authority)
.build();
// Acquire a token, acquireTokenHelper would call publicClientApplication's acquireTokenSilently then acquireToken
// see https://github.com/Azure-Samples/ms-identity-java-desktop for a full example
IAuthenticationResult authenticationResult = acquireTokenHelper(pca);
// Set the appropriate header fields in the request header.
conn.setRequestProperty("Authorization", "Bearer " + authenticationResult.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);
iOS 및 macOS용 MSAL에서 웹 API 호출
토큰을 획득하는 메서드는 MSALResult
개체를 반환합니다. MSALResult
(은)는 API를 호출하는 데 사용할 수 있는 accessToken
속성을 표시합니다. 보호된 웹 API에 액세스하기 위해 호출하기 전에 액세스 토큰을 HTTP 인증 헤더에 추가합니다.
Objective-C:
NSMutableURLRequest *urlRequest = [NSMutableURLRequest new];
urlRequest.URL = [NSURL URLWithString:"https://contoso.api.com"];
urlRequest.HTTPMethod = @"GET";
urlRequest.allHTTPHeaderFields = @{ @"Authorization" : [NSString stringWithFormat:@"Bearer %@", accessToken] };
NSURLSessionDataTask *task =
[[NSURLSession sharedSession] dataTaskWithRequest:urlRequest
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {}];
[task resume];
Swift:
let urlRequest = NSMutableURLRequest()
urlRequest.url = URL(string: "https://contoso.api.com")!
urlRequest.httpMethod = "GET"
urlRequest.allHTTPHeaderFields = [ "Authorization" : "Bearer \(accessToken)" ]
let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data: Data?, response: URLResponse?, error: Error?) in }
task.resume()
여러 API 호출: 증분 동의 및 조건부 액세스
동일한 사용자에 대해 여러 API를 호출하려면 첫 번째 API에 대한 토큰을 가져온 후 AcquireTokenSilent
(을)를 호출합니다. 대부분의 경우 다른 API에 대한 토큰을 자동으로 가져옵니다.
var result = await app.AcquireTokenXX("scopeApi1")
.ExecuteAsync();
result = await app.AcquireTokenSilent("scopeApi2")
.ExecuteAsync();
다음과 같은 경우 상호 작용이 필요합니다.
- 사용자가 첫 번째 API에 대해 동의했지만 이제 더 많은 범위에 동의해야 하는 경우. 이러한 종류의 동의를 증분 동의라고 합니다.
- 첫 번째 API는 다단계 인증이 필요하지 않았지만 다음 API는 필요합니다.
var result = await app.AcquireTokenXX("scopeApi1")
.ExecuteAsync();
try
{
result = await app.AcquireTokenSilent("scopeApi2")
.ExecuteAsync();
}
catch(MsalUiRequiredException ex)
{
result = await app.AcquireTokenInteractive("scopeApi2")
.WithClaims(ex.Claims)
.ExecuteAsync();
}
Axios와 같은 HTTP 클라이언트를 사용하여 권한 부여 전달자로 액세스 토큰을 통해 API 엔드포인트 URI를 호출합니다.
const axios = require('axios');
async function callEndpointWithToken(endpoint, accessToken) {
const options = {
headers: {
Authorization: `Bearer ${accessToken}`
}
};
console.log('Request made at: ' + new Date().toString());
const response = await axios.default.get(endpoint, options);
return response.data;
}
endpoint = "url to the API"
http_headers = {'Authorization': 'Bearer ' + result['access_token'],
'Accept': 'application/json',
'Content-Type': 'application/json'}
data = requests.get(endpoint, headers=http_headers, stream=False).json()