Microsoft.Identity.Web 會新增擴充方法,以提供用來呼叫 Microsoft Graph 或下游 Web API 的便利服務。 這些方法在 呼叫 Web API 的 Web 應用程式:呼叫 API 中有詳細的說明。 使用這些協助程式方法時,您不需要手動取得權杖。
但是,如果您想要以手動方式取得權杖,下列程式碼會示範使用 Microsoft.Identity.Web 在首頁控制器中執行此動作的範例。 它會使用 REST API 呼叫 Microsoft Graph (而非 Microsoft Graph SDK)。 通常,您不需要取得權杖,而是需要建置授權標頭以新增至您的要求。 若要取得授權標頭,您可以透過控制器的建構函式 (如果使用 Blazor,則為頁面建構函式) 中的相依性插入來插入 IAuthorizationHeaderProvider
服務,並在控制器動作中使用。 這個介面有方法可產生包含通訊協定 (Bearer、Pop 等) 和權杖的字串。 若要取得代表使用者呼叫 API 的授權標頭,請使用 (CreateAuthorizationHeaderForUserAsync
)。 若要取得授權標頭來代表應用程式本身呼叫下游 API,請在精靈案例中使用 (CreateAuthorizationHeaderForAppAsync
)。
控制器方法會受到 [Authorize]
屬性的保護,確保僅有已驗證的呼叫可以使用 Web API。
[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
方法的詳細資料,請參閱呼叫 Web API 的 Web API:呼叫 API。
ASP.NET 的程式碼類似於 ASP.NET Core 所顯示的程式碼:
- 由 [授權] 屬性保護的控制器動作,會解壓縮控制器
ClaimsPrincipal
成員的租用戶識別碼與使用者識別碼。 (ASP.NET 使用HttpContext.User
。)Microsoft.Identity.Web.OWIN 會將擴充方法新增至控制器,以提供方便的服務來呼叫 Microsoft Graph 或下游 Web API,或取得授權標頭,甚至是權杖。 呼叫 Web API 的 Web 應用程式:呼叫 API 中詳細介紹了用於直接呼叫 API 的方法。 使用這些協助程式方法時,您不需要手動取得權杖。
不過,如果您確實想要手動取得權杖或建置授權標頭,下列程式碼會示範如何使用 Microsoft.Identity.Web 在控制器中執行此動作。 其會使用 REST API 而不是 Microsoft Graph SDK 來呼叫 API (Microsoft Graph)。
若要取得授權標頭,您可以使用擴充方法 GetAuthorizationHeaderProvider
從控制器取得 IAuthorizationHeaderProvider
服務。 若要取得代表使用者呼叫 API 的授權標頭,請使用 (CreateAuthorizationHeaderForUserAsync
)。 若要取得授權標頭來代表應用程式本身呼叫下游 API,請在精靈案例中使用 (CreateAuthorizationHeaderForAppAsync
)。
控制器方法會受到[Authorize]
屬性的保護,確保僅有已驗證的使用者可以使用 Web 應用程式。
下列程式碼片段顯示 HomeController
的動作,此動作會取得授權標頭,以將 Microsoft Graph 呼叫為 REST API:
[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);
}
}
下列程式碼片段顯示 MyApiController
的動作,此動作會取得存取權杖,以將 Microsoft Graph 呼叫為 REST API:
[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 需要使用中介軟體來驗證接收自用戶端的持有人權杖。 然後,Web 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 和服務可以使用存取權杖快取,以繼續代表使用者執行動作。 如果背景應用程式和服務需要在使用者結束前端 Web 應用程式之後,以使用者身分繼續工作,這項功能就特別有用。
目前,大部分的背景程序在需要用到使用者資料時都會使用應用程式權限,而不需要提供驗證或重新驗證。 因為應用程式權限通常需要管理員同意 (需要提高權限),所以開發人員不想取得使用者原本同意其應用程式的權限時,就會發生不必要的分歧。
此 GitHub 程式碼範例顯示如何從背景應用程式存取 MSAL 的權杖快取,以避免這種不必要的摩擦:
從背景應用程式、API 和服務存取已登入使用者的權杖快取