diff --git a/src/Keycloak.Net/Common/Extensions/FlurlRequestExtensions.cs b/src/Keycloak.Net/Common/Extensions/FlurlRequestExtensions.cs index daed9932..e963e3cd 100644 --- a/src/Keycloak.Net/Common/Extensions/FlurlRequestExtensions.cs +++ b/src/Keycloak.Net/Common/Extensions/FlurlRequestExtensions.cs @@ -11,16 +11,16 @@ public static class FlurlRequestExtensions private static async Task GetAccessTokenAsync(string url, string realm, string userName, string password) { var result = await url - .AppendPathSegment($"/auth/realms/{realm}/protocol/openid-connect/token") - .WithHeader("Accept", "application/json") - .PostUrlEncodedAsync(new List> - { - new KeyValuePair("grant_type", "password"), - new KeyValuePair("username", userName), - new KeyValuePair("password", password), - new KeyValuePair("client_id", "admin-cli") - }) - .ReceiveJson().ConfigureAwait(false); + .AppendPathSegment($"/auth/realms/{realm}/protocol/openid-connect/token") + .WithHeader("Accept", "application/json") + .PostUrlEncodedAsync(new List> + { + new KeyValuePair("grant_type", "password"), + new KeyValuePair("username", userName), + new KeyValuePair("password", password), + new KeyValuePair("client_id", "admin-cli") + }) + .ReceiveJson().ConfigureAwait(false); string accessToken = result .access_token.ToString(); @@ -30,15 +30,45 @@ private static async Task GetAccessTokenAsync(string url, string realm, private static string GetAccessToken(string url, string realm, string userName, string password) => GetAccessTokenAsync(url, realm, userName, password).GetAwaiter().GetResult(); - public static IFlurlRequest WithAuthentication(this IFlurlRequest request, Func getToken, string url, string realm, string userName, string password) + private static async Task GetAccessTokenAsync(string url, string realm, string clientSecret) { + var result = await url + .AppendPathSegment($"/auth/realms/{realm}/protocol/openid-connect/token") + .WithHeader("Content-Type", "application/x-www-form-urlencoded") + .PostUrlEncodedAsync(new List> + { + new KeyValuePair("grant_type", "client_credentials"), + new KeyValuePair("client_secret", clientSecret), + new KeyValuePair("client_id", "admin-cli") + }) + .ReceiveJson().ConfigureAwait(false); + + string accessToken = result + .access_token.ToString(); + + return accessToken; + } + + private static string GetAccessToken(string url, string realm, string clientSecret) => GetAccessTokenAsync(url, realm, clientSecret).GetAwaiter().GetResult(); + + public static IFlurlRequest WithAuthentication(this IFlurlRequest request, Func getToken, string url, string realm, string userName, string password, string clientSecret) + { + string token = null; + if (getToken != null) { - string token = getToken(); - return request.WithOAuthBearerToken(token); + token = getToken(); + } + else if (clientSecret != null) + { + token = GetAccessToken(url, realm, clientSecret); + } + else + { + token = GetAccessToken(url, realm, userName, password); } - return request.WithOAuthBearerToken(GetAccessToken(url, realm, userName, password)); + return request.WithOAuthBearerToken(token); } public static IFlurlRequest WithForwardedHttpHeaders(this IFlurlRequest request, ForwardedHttpHeaders forwardedHeaders) diff --git a/src/Keycloak.Net/KeycloakClient.cs b/src/Keycloak.Net/KeycloakClient.cs index 5657d4c3..0e00371d 100755 --- a/src/Keycloak.Net/KeycloakClient.cs +++ b/src/Keycloak.Net/KeycloakClient.cs @@ -1,52 +1,59 @@ -using System; -using Flurl; -using Flurl.Http; -using Flurl.Http.Configuration; -using Keycloak.Net.Common.Extensions; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Keycloak.Net -{ - public partial class KeycloakClient - { - private ISerializer _serializer = new NewtonsoftJsonSerializer(new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver(), - NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore - }); - - private readonly Url _url; - private readonly string _userName; - private readonly string _password; - private readonly Func _getToken; - - private KeycloakClient(string url) - { - _url = url; - } - - public KeycloakClient(string url, string userName, string password) - : this(url) - { - _userName = userName; - _password = password; - } - - public KeycloakClient(string url, Func getToken) - : this(url) - { - _getToken = getToken; - } - - public void SetSerializer(ISerializer serializer) +using System; +using Flurl; +using Flurl.Http; +using Flurl.Http.Configuration; +using Keycloak.Net.Common.Extensions; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Keycloak.Net +{ + public partial class KeycloakClient + { + private ISerializer _serializer = new NewtonsoftJsonSerializer(new JsonSerializerSettings { - _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); - } - - private IFlurlRequest GetBaseUrl(string authenticationRealm) => new Url(_url) - .AppendPathSegment("/auth") - .ConfigureRequest(settings => settings.JsonSerializer = _serializer) - .WithAuthentication(_getToken, _url, authenticationRealm, _userName, _password); - } -} + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore + }); + + private readonly Url _url; + private readonly string _userName; + private readonly string _password; + private readonly string _clientSecret; + private readonly Func _getToken; + + private KeycloakClient(string url) + { + _url = url; + } + + public KeycloakClient(string url, string userName, string password) + : this(url) + { + _userName = userName; + _password = password; + } + + public KeycloakClient(string url, string clientSecret) + : this(url) + { + _clientSecret = clientSecret; + } + + public KeycloakClient(string url, Func getToken) + : this(url) + { + _getToken = getToken; + } + + public void SetSerializer(ISerializer serializer) + { + _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); + } + + private IFlurlRequest GetBaseUrl(string authenticationRealm) => new Url(_url) + .AppendPathSegment("/auth") + .ConfigureRequest(settings => settings.JsonSerializer = _serializer) + .WithAuthentication(_getToken, _url, authenticationRealm, _userName, _password, _clientSecret); + } +}