API Client¶
Ein API Client ist eine Anwendung, die auf eine Web API zugreifen muss, die einen gültigen Bearer Token erfordert, der vom IdentityServerNET ausgestellt wurde.
API Resource¶
Um einen Bearer Token für eine API auszustellen, muss diese API zuerst als
API Resource angelegt werden. Dazu navigiert man über die Admin-Seite zu
Resources (Identity & APIs)/API Resources.
Dort kann eine neue API Resource angelegt werden:
Im nächsten Schritt müssen für die API Resource mögliche Scopes erstellt werden:
Bemerkung
Die Namenskonvention für API Resource Scopes ist: api-resource-name.scope-name.
Wenn ein Scope eingegeben wird, wird er automatisch in dieses Format umgewandelt. Eine Ausnahme ist ein Scope,
der den gleichen Namen hat wie die api-resource. Möchte man einen Scope anlegen, der von dieser
Konvention abweicht, muss dieser mit vorangestelltem @@ angegeben werden, z. B. @@scope-name.
Für eine API werden nach dem Erstellen automatisch folgende Scopes angelegt:
{api-name}: Allgemeiner Zugriff auf die API{api-name}.query: Lesezugriff auf die von der API bereitgestellten Daten{api-name}.command: Zusätzlich Schreibzugriff auf die von der API bereitgestellten Daten
Bemerkung
Der Scope {api-name} sollte später unbedingt als Scope bei einem Client hinzugefügt werden. Er entspricht
der Audience (aud) des Tokens!
API Client erstellen/bearbeiten¶
Um einen neuen Client zu erstellen, muss eine eindeutige Client Id vergeben werden. Optional kann auch ein sprechender Name zugewiesen werden.
Damit nicht alles manuell eingegeben werden muss, sollte als Template API gewählt
werden. Außerdem sollte in diesem Template die URL zur Webanwendung eingetragen werden. Die Eingabe der Scopes ist optional und kann
auch im nächsten Schritt bearbeitet werden:
Nach erfolgreicher Erstellung des Clients gelangt man zur Seite Modify Client: .... Hier sind die
verschiedenen Eigenschaften des Clients in Menüpunkten gegliedert:
Name:¶
Hier kann der Name des Clients geändert und eine Beschreibung hinzugefügt werden.
Client Secrets¶
Hier muss ein Secret angegeben werden, mit dem sich der Client am Identity Server authentifizieren muss. Über den
Random Secret Generator kann ein sicheres Secret erzeugt werden. Für dieses Beispiel verwenden wir das einfache Secret secret:
Allowed Grants¶
Da beim Erstellen des Clients der Typ ApiClient gewählt wurde, sollte hier ClientCredentials ausgewählt sein:
Allowed Scopes¶
Hier müssen die Scopes hinzugefügt werden, die für die API Resource erstellt wurden. Die Scopes bestimmen in der
API später spezielle Zugriffsrechte. Beim my-api-command Client macht es Sinn, den my-api und
den my-api.command Scope aus dem Bereich Add existing resource scope zu übernehmen:
Advanced Properties¶
Hier kann beispielsweise die Lebensdauer eines AccessTokens definiert werden:
Bemerkung
Alle weiteren Menüpunkte sind für API Clients weniger relevant und werden hier nicht im Detail aufgelistet.
Abholen eines AccessTokens¶
HTTP Request¶
Eine Client-Anwendung kann über einen HTTP POST Request mit den notwendigen Parametern im Body ein AccessToken von IdentityServerNET abholen.
Die Scopes werden über den Parameter scope übergeben, wobei Leerzeichen als Trennzeichen verwendet werden:
POST https://localhost:44300/connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=my-api-commands&client_secret=secret&scope=my-api my-api.command
bzw.
POST https://localhost:44300/connect/token
Authorization: Basic bXktYXBpLWNvbW1hbmRzOnNlY3JldA==
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&scope=my-api.command my-api
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkVCM...",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "my-api my-api.command"
}
… note:
Der ``scope`` Parameter kann auch weggelassen werden. In diesem Fall enthält der Token alle für den Client eingestellten Scopes.
IdentityServerNET.Clients¶
Zum Abholen eines Tokens kann auch das NuGet-Paket IdentityServerNET.Clients verwendet werden:
dotnet add package IdentityServerNET.Clients
var tokenClient = new IdentityServerNET.Clients.TokenClient("my-api-commands", "secret");
await tokenClient.GetAccessToken("https://localhost:44300", []);
var accessToken = tokenClient.AccessToken;
IdentityModel¶
IdentityModel bietet ebenfalls eine Möglichkeit, einen Token abzuholen:
dotnet add package IdentityModel
var client = new HttpClient();
// Entdecke den Endpunkt des IdentityServers
var discovery = await client.GetDiscoveryDocumentAsync("https://localhost:44300");
if (discovery.IsError)
{
Console.WriteLine(discovery.Error);
return;
}
// Get tht Token
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = discovery.TokenEndpoint,
ClientId = "my-api-commands",
ClientSecret = "secret",
Scope = "my-api my-api.command"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.AccessToken);