Après avoir généré un objet d’application cliente, utilisez-le pour acquérir un jeton qui vous servira à appeler une API web.
Microsoft.Identity.Web ajoute des méthodes d’extension qui fournissent des services pratiques pour appeler Microsoft Graph ou une API web en aval. Ces méthodes sont expliquées en détail dans Application web qui appelle des API web : Appeler une API. Avec ces méthodes d’assistance, vous n’avez pas besoin d’acquérir manuellement un jeton.
Toutefois, si vous souhaitez acquérir manuellement un jeton, le code suivant montre un exemple d’utilisation de Microsoft.Identity.Web pour le faire dans un contrôleur home. Il appelle Microsoft Graph à l’aide de l’API REST (au lieu du Kit de développement logiciel (SDK) Microsoft Graph). En règle générale, vous n’avez pas besoin d’obtenir un jeton, juste de créer un en-tête d’autorisation que vous ajoutez à votre requête. Pour obtenir un jeton d’autorisation, vous injectez le service IAuthorizationHeaderProvider
par injection de dépendances dans le constructeur de votre contrôleur (ou votre constructeur de page si vous utilisez Blazor), puis vous l’utilisez dans les actions de votre contrôleur. Cette interface propose des méthodes qui produisent une chaîne contenant le protocole (Porteur, Pop, ...) et un jeton. Pour obtenir un en-tête d’autorisation pour appeler une API au nom de l’utilisateur, utilisez (CreateAuthorizationHeaderForUserAsync
). Pour obtenir un en-tête d’autorisation pour appeler une API en aval pour le compte de l’application elle-même, dans un scénario démon, utilisez (CreateAuthorizationHeaderForAppAsync
).
Les méthodes de contrôleur sont protégées par un attribut [Authorize]
qui veille à ce que seuls des appels authentifiés puissent utiliser l’API web.
[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);
}
}
Pour plus d’informations sur la méthode callTodoListService
, consultez Une API web qui appelle des API web : Appeler une API.
Le code pour ASP.NET est similaire au code présenté pour ASP.NET Core :
- Une action de contrôleur, protégée par un attribut [Authorize], extrait l’ID de locataire et l’identifiant utilisateur du membre
ClaimsPrincipal
du contrôleur. (ASP.NET utilise HttpContext.User
.) Microsoft.Identity.Web.OWIN ajoute des méthodes d’extension au contrôleur qui fournissent des services pratiques pour appeler Microsoft Graph ou une API web en aval, ou pour obtenir un en-tête d’autorisation, voire un jeton. Les méthodes servant à appeler directement une API sont expliquées en détail dans l’article Application web appelant des API web : Appeler une API. Avec ces méthodes d’assistance, vous n’avez pas besoin d’acquérir manuellement un jeton.
Toutefois, si vous souhaitez acquérir manuellement un jeton ou créer un en-tête d’autorisation, le code suivant montre comment utiliser Microsoft.Identity.Web pour le faire dans un contrôleur. Il appelle une API (Microsoft Graph) à l’aide de l’API REST en lieu et place du Kit de développement logiciel (SDK) Microsoft Graph.
Pour obtenir un en-tête d’autorisation, vous obtenez un service IAuthorizationHeaderProvider
du contrôleur à l’aide d’une méthode d’extension GetAuthorizationHeaderProvider
. Pour obtenir un en-tête d’autorisation pour appeler une API au nom de l’utilisateur, utilisez (CreateAuthorizationHeaderForUserAsync
). Pour obtenir un en-tête d’autorisation pour appeler une API en aval pour le compte de l’application elle-même, dans un scénario démon, utilisez (CreateAuthorizationHeaderForAppAsync
).
Les méthodes de contrôleur sont protégées par un attribut [Authorize]
qui veille à ce que seuls des utilisateurs authentifiés puissent utiliser l’application web.
L’extrait de code suivant montre l’action de HomeController
, qui obtient un en-tête d’autorisation pour appeler Microsoft Graph en tant qu’API REST :
[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);
}
}
L’extrait de code suivant montre l’action de MyApiController
, qui obtient un jeton d’accès pour appeler Microsoft Graph en tant qu’API REST :
[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);
}
}
Voici un exemple de code appelé dans les actions des contrôleurs d’API. Il appelle l'API situé en aval, 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);
}
}
Une API web Python doit utiliser un middleware pour valider le jeton du porteur reçu du client. L’API web peut alors obtenir le jeton d’accès de l’API située en aval à l’aide de la bibliothèque MSAL Python en appelant la méthode acquire_token_on_behalf_of
.
Voici un exemple de code qui acquiert un jeton d’accès à l’aide de la méthode acquire_token_on_behalf_of
et du framework Flask. Il appelle l’API en aval (le point de terminaison des abonnements de gestion 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)
(Avancé) Accès au cache de jeton de l’utilisateur connecté à partir d’applications en arrière-plan, d’API et de services
Vous pouvez utiliser l’implémentation du cache de jeton MSAL pour permettre aux applications, aux API et aux services en arrière-plan d’utiliser le cache de jeton d’accès afin de continuer à agir au nom des utilisateurs en leur absence. Cela s’avère particulièrement utile si les applications et les services en arrière-plan doivent continuer à travailler au nom de l’utilisateur une fois que celui-ci a quitté l’application web front-end.
Aujourd’hui, la plupart des processus en arrière-plan utilisent des autorisations d’application lorsqu’ils doivent travailler avec les données d’un utilisateur sans que l’utilisateur soit présent pour l’authentification ou la réauthentification. Étant donné que les autorisations d’application requièrent souvent un consentement de l’administrateur, ce qui nécessite une élévation des privilèges, un conflit inutile est décelé, car le développeur n’avait pas l’intention d’obtenir une autorisation au-delà de celle consentie à l’origine par l’utilisateur pour son application.
Cet exemple de code sur GitHub montre comment éviter ce conflit inutile en accédant au cache de jeton MSAL à partir d’applications en arrière-plan :
Accès au cache de jeton de l’utilisateur connecté à partir d’applications, d’API et de services en arrière-plan