Einleitung
Um das CoreOne Suite Application Interface zu benutzer oder auf eine andere über OpenId angebundene Applikation mittels API Benutzer zuzugreifen, müssen sie einen Access Token lösen. Dieser Artikel beschreibt wie ein solcher Token gelöst werden kann.
Vorbedingungen
Folgende Vorbedingungen müssen erfüllt sein um einen Access Token lösen zu können.
1 | Applikation registrieren | Die Applikation von welcher sie auf das Application Interface zugreifen möchten muss in der CoreOne Suite erfasst sein und mit einem client_secret belegt sein |
2 | API Benutzer | Sie müssen einen Benutzer eingerichtet haben, der über die Berechtigungen verfügt um die gewünschte API Funktion aufzurufen |
3 | Token Endpoint | Sie benötigen die URL auf welchem der Token Endpoint konfiguriert ist. Diese sieht in etwa wie folgt aus: |
Access Token lösen
Sind alle vorbedingungen erfüllt kann ein Access Token über folgende Schritte gelöst werden.
1 | Ermitteln des Token Endopoints | Rufen sie den Discovery Endpoint auf. private static async Task<string> GetTokenEndpointUri(string discoUri) { using (var httpClient = new HttpClient()) { //Create a simple GET-Request to the Discovery-Uri var discoDoc = await httpClient.GetStringAsync(discoUri); //return the property token_endpoint from GET-Response var discoElement = (dynamic)JsonConvert.DeserializeObject(discoDoc); return (string)discoElement.token_endpoint; } } |
2 | Zusammenstellen der Parameter | Folgende Parameter müssen im Token Request enthalten sein:
|
3 | Abfragen des Access Tokens | Durch ein einfaches HTTP Post auf den zuvor ermittelten Token Endpoint kann der Access Token gelöst werden. using (var httpClient = new HttpClient()) { //Use Client-Identifier / Client-Secret for Basic-Authentication httpClient.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(tokenRequest.ClientIdentifier, tokenRequest.ClientSecret); //Create a POST request to the token-endpoint with data in FormUrlEncoded format var tokenResponse = await httpClient.PostAsync(tokenRequest.TokenEndppointUri, new FormUrlEncodedContent(new Dictionary<string, string> { {"grant_type" , "password"}, {"username", "someUserName" }, {"password", "somePassword" }, {"scope", "openid c1s_api roles" })} })); //return the property access_token from POST-Response var tokenResponseDoc = await tokenResponse.Content.ReadAsStringAsync(); var tokenElement = (dynamic)JsonConvert.DeserializeObject(tokenResponseDoc); var result = (string)tokenElement.access_token; } |
Komplettes Beispiel
Das oben vereinfachte Beispiel ist hier in kompletter Form zu finden.
using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; namespace ConsoleResourceOwnerFlowRefreshToken { public class Program { public static void Main(string[] args) => MainAsync().GetAwaiter().GetResult(); private static async Task MainAsync() { string tokenEndpoint = null; while (tokenEndpoint == null) { Console.Clear(); Console.WriteLine("Get TokenEndpoint"); try { tokenEndpoint = await GetTokenEndpointUri("https://localhost:5000/.well-known/openid-configuration"); } catch (Exception e) { Console.WriteLine(); Console.WriteLine($"Error: {e}"); Console.WriteLine(); Console.WriteLine("Press q to quit or any other key to retry"); if (char.ToLower(Console.ReadKey().KeyChar) == 'q') return; tokenEndpoint = null; } } var tokenRequest = new TokenRequest { TokenEndppointUri = tokenEndpoint, Scopes = new[] { "openid", "c1s_api", "roles" }, ClientIdentifier = "anyClient", ClientSecret = "anySecret", Username = "someUserName", Password = "someUserPassword" }; do { Console.Clear(); try { Console.WriteLine($"Token-Endpoint: {tokenEndpoint}"); Console.WriteLine(); var token = await GetToken(tokenRequest); Console.WriteLine(token ?? "null"); } catch (Exception e) { Console.WriteLine($"Error: {e}"); } Console.WriteLine(); Console.WriteLine("Press q to quit or any other key to renew token"); } while (char.ToLower(Console.ReadKey().KeyChar) != 'q'); } private static async Task<string> GetToken(TokenRequest tokenRequest) { using (var httpClient = new HttpClient()) { //Use Client-Identifier / Client-Secret for Basic-Authentication httpClient.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(tokenRequest.ClientIdentifier, tokenRequest.ClientSecret); //Create a POST request to the token-endpoint with data in FormUrlEncoded format var tokenResponse = await httpClient.PostAsync(tokenRequest.TokenEndppointUri, new FormUrlEncodedContent(new Dictionary<string, string> { {"grant_type" , "password"}, {"username", tokenRequest.Username }, {"password", tokenRequest.Password }, {"scope", string.Join(" ", tokenRequest.Scopes)} })); //return the property access_token from POST-Response var tokenResponseDoc = await tokenResponse.Content.ReadAsStringAsync(); var tokenElement = (dynamic)JsonConvert.DeserializeObject(tokenResponseDoc); return (string)tokenElement.access_token; } } private static async Task<string> GetTokenEndpointUri(string discoUri) { using (var httpClient = new HttpClient()) { //Create a simple GET-Request to the Discovery-Uri var discoDoc = await httpClient.GetStringAsync(discoUri); //return the property token_endpoint from GET-Response var discoElement = (dynamic)JsonConvert.DeserializeObject(discoDoc); return (string)discoElement.token_endpoint; } } } public class TokenRequest { public string TokenEndppointUri { get; set; } public string ClientIdentifier { get; set; } public string ClientSecret { get; set; } public string Username { get; set; } public string Password { get; set; } public string[] Scopes { get; set; } } }
Verwandte Artikel