Una vez que ha creado un objeto de aplicación cliente, lo puede usar para adquirir un token y usarlo para llamar a una API web.
Microsoft.Identity.Web agrega métodos de extensión que proporcionan servicios útiles para llamar a Microsoft Graph o a una API web de nivel inferior. Estos métodos se explican con detalle en Aplicación web que llama a las API web: llamada a una API. Con estos métodos auxiliares, no es necesario adquirir un token manualmente.
Sin embargo, si desea adquirir manualmente un token, el código siguiente muestra un ejemplo de uso de Microsoft.Identity.Web para hacerlo en un controlador de inicio. Llama a Microsoft Graph mediante la API REST (en lugar del SDK de Microsoft Graph). Normalmente, no es necesario obtener un token; debe crear un encabezado de autorización que agregue a la solicitud. Para obtener un encabezado de autorización, inyecte el servicio IAuthorizationHeaderProvider
mediante inyección de dependencia en el constructor de su controlador (o en el constructor de su página si utiliza Blazor), y utilícelo en las acciones de su controlador. Esta interfaz tiene métodos que generan una cadena que contiene el protocolo (Portador, Pop, ...) y un token. Para obtener un encabezado de autorización para llamar a una API en nombre del usuario, use (CreateAuthorizationHeaderForUserAsync
). Para obtener un encabezado de autorización para llamar a una API de bajada en nombre de la propia aplicación, en un escenario de demonio, use (CreateAuthorizationHeaderForAppAsync
).
Los métodos del controlador están protegidos por el atributo [Authorize]
, que garantiza que solo las llamadas autenticadas pueden usar la 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);
}
}
Para más información sobre el método callTodoListService
, consulte API web que llama a API web: Llamada a una API.
El código para ASP.NET es similar al que se muestra para ASP.NET Core:
- Una acción de controlador protegida por un atributo [Authorize] extrae el identificador de inquilino y el identificador de usuario del miembro
ClaimsPrincipal
del controlador. (ASP.NET usa HttpContext.User
). Microsoft.Identity.Web.OWIN agrega métodos de extensión al controlador que proporcionan servicios prácticos para llamar a Microsoft Graph o a una API web de bajada, o para obtener un encabezado de autorización o incluso un token. Los métodos utilizados para llamar directamente a una API se explican con detalle en Aplicación web que llama a las API web: llamada a una API. Con estos métodos auxiliares, no es necesario adquirir un token manualmente.
Sin embargo, si desea adquirir manualmente un token o crear un encabezado de autorización, el siguiente código muestra cómo utilizar Microsoft.Identity.Web para hacerlo en un controlador. Llama a una API (Microsoft Graph) mediante la API de REST, en lugar del SDK de Microsoft Graph.
Para obtener un encabezado de autorización, obtenga un servicio de IAuthorizationHeaderProvider
del controlador mediante un método de extensión GetAuthorizationHeaderProvider
. Para obtener un encabezado de autorización para llamar a una API en nombre del usuario, use (CreateAuthorizationHeaderForUserAsync
). Para obtener un encabezado de autorización para llamar a una API de bajada en nombre de la propia aplicación, en un escenario de demonio, use (CreateAuthorizationHeaderForAppAsync
).
Los métodos del controlador están protegidos por el atributo [Authorize]
, que garantiza que solo los usuarios autenticados pueden usar la aplicación web.
En el fragmento de código siguiente se muestra la acción de HomeController
, que obtiene un encabezado de autorización para llamar a Microsoft Graph como una API de 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);
}
}
En el fragmento de código siguiente se muestra la acción de MyApiController
, que obtiene un token de acceso para llamar a Microsoft Graph como una API de 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);
}
}
A continuación, se muestra un ejemplo de código que se llama en las acciones de los controladores de API. Llama a la API de nivel inferior de 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);
}
}
Una API web de Python requiere el uso de middleware para validar el token de portador recibido del cliente. A continuación, la API web podrá obtener el token de acceso para una API de nivel inferior mediante la biblioteca de MSAL para Python al llamar al método acquire_token_on_behalf_of
.
A continuación se muestra un ejemplo de código que adquiere un token de acceso mediante el método acquire_token_on_behalf_of
y el marco de Flask. Llama a la API de nivel inferior: el punto de conexión de suscripciones de Azure Management.
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)
(Avanzado) Acceso a la memoria caché de tokens del usuario que ha iniciado sesión desde aplicaciones en segundo plano, API y servicios
Puede usar la implementación de la caché de tokens de MSAL para permitir que las aplicaciones, las API y los servicios en segundo plano usen la caché de tokens de acceso para continuar actuando en nombre de los usuarios en su ausencia. Hacerlo resulta especialmente útil si las aplicaciones y los servicios en segundo plano deben seguir trabajando en nombre del usuario después de que haya salido de la aplicación web de front-end.
En la actualidad, la mayoría de los procesos en segundo plano usan permisos de aplicación cuando necesitan trabajar con los datos de un usuario sin que este esté presente para autenticarse o volver a autenticarse. Dado que los permisos de aplicación suelen requerir el consentimiento del administrador, lo que requiere la elevación de privilegios, se genera una fricción innecesaria porque el desarrollador no tenía la intención de obtener permiso más allá del que el usuario dio su consentimiento originalmente para su aplicación.
En este ejemplo de código en GitHub se muestra cómo evitar esta fricción innecesaria mediante el acceso a la caché de tokens de MSAL desde las aplicaciones en segundo plano:
Acceso a la memoria caché de tokens del usuario que ha iniciado sesión desde aplicaciones en segundo plano, API y servicios