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 9 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.

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:

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.

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:

  • grant_type → password

  • username → Der Benutzername des API Benutzers

  • password → Das Passwort des API Benutzers

  • scope → Die gewünschten Scopes

3

Abfragen 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.

Verwandte Artikel


  • No labels