Web API, clients externes et OAuth 2
Cette page couvre deux besoins distincts :
- exposer certains contrôleurs Lagoon à une application externe ;
- appeler une API externe qui utilise OAuth comme mécanisme d'authentification.
Exposer des contrôleurs à un client externe
Si vous souhaitez exposer certains contrôleurs pour permettre à une application externe d'accéder aux données de votre application, créez un accès externe. Par défaut, seul le client de votre application peut accéder aux contrôleurs.
Pour créer un accès externe, vous devez spécifier :
- un identifiant unique ;
- un mot de passe ;
- les rôles associés.
Le client aura accès à tous les contrôleurs sécurisés par les rôles spécifiés.
Ajouter un client externe
protected override void OnConfigureAuthentification(AuthenticationOptions options)
{
// Ajoute un accès externe aux API sans authentification en tant qu'utilisateur.
options.AddClientWithCredential(
"SampleApiConsumption",
"mySecret",
new string[] { Roles.Admin.ToString() });
// Ajoute un accès externe aux API qui exigent une authentification utilisateur.
options.AddClientWithCredentialAndCode(
"ConnectCommand",
"mySecret",
"http://localhost:5002");
}
Communiquez au client qui doit accéder à l'API le ClientId, par exemple SampleApiConsumption, et le ClientSecret, par exemple mySecret.
Avec ces informations, l'application externe peut accéder aux contrôleurs avec le rôle Admin.
Accéder aux contrôleurs depuis un client externe
private async Task GetDataFromApiAsync()
{
string baseAddress = "https://localhost:5001";
HttpClient client = new HttpClient();
DiscoveryDocumentResponse disco = await client.GetDiscoveryDocumentAsync(baseAddress);
if (disco.IsError)
{
throw new Exception(disco.Error);
}
// Demande un jeton avec le client et son secret.
TokenResponse tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "SampleApiConsumption",
ClientSecret = "mySecret"
});
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
// Appelle l'API avec le Bearer token.
HttpClient apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);
HttpResponseMessage response = await apiClient.GetAsync($"{baseAddress}/api/data/GetDemoData");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
string content = await response.Content.ReadAsStringAsync();
}
}
Tester avec Postman
Pour vérifier les URL du projet, les autorisations et le token endpoint, exécutez une requête vers l'URL de découverte https://localhost:5001/.well-known/openid-configuration.
Pensez à désactiver la vérification SSL dans les paramètres généraux de Postman lorsque vous testez en local.
Appeler une API externe avec OAuth 2
Lagoon ne fournit pas de helper serveur dédié pour injecter automatiquement un jeton OAuth 2 dans un HttpClient. Si votre application doit appeler une API externe, utilisez les mécanismes .NET standard (AddHttpClient, IHttpClientFactory) et implémentez explicitement l'acquisition puis l'ajout de l'en-tête Authorization.
Configuration applicative
Ajoutez une section applicative décrivant l'API à appeler et les informations OAuth.
{
"ExternalApi": {
"BaseUrl": "https://api.monservice.com",
"OAuth2": {
"TokenEndpoint": "https://api-authorization/oauth2/v2.0/token",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"Scopes": [ "https://api.monservice.com/.default" ]
}
}
}
Créer le client côté serveur
protected override void OnConfigureServices(IServiceCollection services)
{
Services.Registry.RegisterServices(services);
services.AddHttpClient("ExternalApi", client =>
{
client.BaseAddress = new Uri(Configuration["ExternalApi:BaseUrl"]);
});
}
Utiliser le client dans un service ou un contrôleur
public class ExternalApiService
{
private readonly IHttpClientFactory _httpClientFactory;
public ExternalApiService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<string> GetDataAsync(CancellationToken cancellationToken = default)
{
HttpClient client = _httpClientFactory.CreateClient("ExternalApi");
string accessToken = await GetAccessTokenAsync(cancellationToken);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
using HttpResponseMessage response = await client.GetAsync("/api/resource", cancellationToken);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync(cancellationToken);
}
}
La méthode GetAccessTokenAsync est propre à l'application : elle doit appeler le fournisseur OAuth 2 externe avec les paramètres attendus par ce fournisseur.