Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »


Einleitung

Um das CoreOne Suite Application Interface (API) zu benutzen oder auf eine andere über OpenID angebundene Applikation mittels API Benutzer zuzugreifen, muss ein Access-Token gelöst werden. Dieser Artikel beschreibt wie ein solcher Access-Token gelöst werden kann.


Vorbedingungen

Folgende Vorbedingungen müssen erfüllt sein um einen Access Token lösen zu können.

1Applikation registrierenDie 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.
2API BenutzerSie müssen einen Benutzer eingerichtet haben, der über die Berechtigungen verfügt um die gewünschte API Funktion aufzurufen.
3Token Endpoint

Sie benötigen die URL auf welchem der Token Endpoint konfiguriert ist. Diese sieht in etwa wie folgt aus:

https://localhost:5000/.well-known/openid-configuration

Access-Token lösen (3rd party lib IdentityModel)

Am einfachsten kann ein gültiger AccessToken mithilfe des nuget-packages IdentityModel gelöst werden.

Eine Beispiel-Konsolenapplikation kann hier heruntergeladen werden

var disco = await DiscoveryClient.GetAsync(discoUri);
var tokenClient = new TokenClient(disco.TokenEndpoint, "client-name", "client-secret");
var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("username", "password", "scopes");
if (tokenResponse.IsError)
{
	throw new Exception(tokenResponse.Error);
}
return tokenResponse.AccessToken

Access-Token lösen (Manuell)

Sind alle Vorbedingungen erfüllt, kann ein Access-Token über folgende Schritte gelöst werden.


1Ermitteln 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;
	}
}
2Zusammenstellen der Parameter

Folgende Parameter müssen im Token Request enthalten sein:

  • grant_type → password
  • username → Der Benutzername des API Benutzers
  • password → Das Passwort des API Benutzers
  • scope → Die gewünschten Scopes
3Abfragen des Access-Token

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;
}

Vollständiges Beispiel (Manuell)

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; }
    }
}

Postman

In Postman kann auch direkt ein Token gelöst werden. Dafür muss unter Authorization der Typ OAuth 2.0 ausgewählt werden.

  • No labels