silentpartnersoftware / keycloak.net Goto Github PK
View Code? Open in Web Editor NEWThis project forked from lvermeulen/keycloak.net
C# client for Keycloak version 17+
License: MIT License
This project forked from lvermeulen/keycloak.net
C# client for Keycloak version 17+
License: MIT License
As far as I know, the GetUsersAsync
does not return realm roles assigned to the user. Assuming I have 100 users and 3 roles, which are assigned to these users (1 user can have 1, 2 or all roles).
What would be the most efficient way to fetch the list of users with all their roles?
I get the exception after migrating from Keycloak 23.0.4 to 24.0.4. With 23.0.4 the below code works fine.
Image quay.io/keycloak/keycloak:24.0.4
.Net App Code:
private readonly KeycloakClient _client = new KeycloakClient(
config["Keycloak:KeycloakUrl"],
config["Keycloak:AdminClientUserName"],
config["Keycloak:AdminClientPassword"]
);
private readonly string _realmName = config["Keycloak:RealmName"] ?? throw new InvalidOperationException();
await _client.GetServerInfoAsync(_realmName); // Here is the exception thrown
Exception:
Flurl.Http.FlurlParsingException: Response could not be deserialized to JSON: GET http://ds.keycloak:8080/admin/serverinfo/
---> Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: [. Path 'componentTypes['org.keycloak.keys.KeyProvider'][4].properties[3].defaultValue', line 1, position 157256.
at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
at Flurl.Http.Configuration.NewtonsoftJsonSerializer.Deserialize[T](Stream stream)
at Flurl.Http.FlurlResponse.GetJsonAsync[T]()
--- End of inner exception stack trace ---
at Flurl.Http.FlurlRequest.HandleExceptionAsync(FlurlCall call, Exception ex, CancellationToken token)
at Flurl.Http.FlurlResponse.GetJsonAsync[T]()
at Flurl.Http.ResponseExtensions.ReceiveJson[T](Task`1 response)
at Keycloak.Net.KeycloakClient.GetServerInfoAsync(String realm, CancellationToken cancellationToken)
...
Whilst trying to retrieve a list of the admin events on a keycloak instance using GetAdminEventsAsync(realmName), the following error is provided:
JsonReaderException: JSON integer 1660122818885 is too large or small for an Int32. Path '[0].time', line 1, position 22.
After a little digging around it seems that this should most likely be a long? rather than an int?.
I am happy to create a branch for this to make that one small change but it will likely also affect other models that use the same way of working with time.
I tried using KeycloakClient.GetUserForServiceAccountAsync()
and it was working fine. Why is this marked as obsolete? It is important to use the clients id
(uuid) not the clientId
for this request to work correctly (See #30)
Keycloak.Net/src/Keycloak.Net.Core/Clients/KeycloakClient.cs
Lines 268 to 272 in 8ef20d1
Hi,
It doesn't look nice to request a token for every operation.
Even if we get a new token when it expires, the same problem persists across multiple instance.
I tried with ServiceAccount + BasicAuth but couldn't succeed. I'm not sure if it's supported.
What do you think about this? Is there another way?
Thank you.
When create a new client-scope, cannot set "display on consent screen" to false.
Keycloak version: 21.0.1
the client-scope attributes can't be sealized correctly. For example, the property "DisplayOnConsentScreen" has been serialized "displayonconsentscreen" but need to be serialized as "display.on.consent.screen"
I had been tested this change with postman successful
The CreateAndRetrieveUserIdAsync
isn't compatible with flurl 3.* versions:
System.MissingMethodException: Method not found: 'System.Threading.Tasks.Task`1<System.Net.Http.HttpResponseMessage> Flurl.Http.GeneratedExtensions.PostJsonAsync(Flurl.Http.IFlurlRequest, System.Object, System.Threading.CancellationToken, System.Net.Http.HttpCompletionOption)'.
at Keycloak.Net.KeycloakClient.InternalCreateUserAsync(String realm, User user, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Keycloak.Net.KeycloakClient.InternalCreateUserAsync(String realm, User user, CancellationToken cancellationToken)
at Keycloak.Net.KeycloakClient.CreateAndRetrieveUserIdAsync(String realm, User user, CancellationToken cancellationToken)
If I downgrade to 2.*, it works
I was looking for out of the box ideas for using keycloak.
Since we will integrate keycloak v20+ for another project I am currently in the exploration phase for integrating it.
Ive found solutions targetting .net 4.7, but for lower versions of KC, and targetting higher versions of KC for .net 6.0
Assuming upgrading to 6.0 is not a viable option right now, I would be looking at making this repo compatible with 4.7.
I am asking the maintainer if this is a "no go" for syntastic reasons, dependencies. Or do you have pointers as to what and how.
Else I'll try to implement it file by file.
Kind regards,
I'm trying to create a client scope. The call is successful, but the UI of Keycloak throws an error when I want to display my new client scope.
Error message in UI: "Danger alert:n is undefined Press here to refresh and continue"
It is noticeable that openid-connect value in protocol is displayed incorrectly. For all other items "OpenID Connect" is display, but for my new client scope "openid-connect" is displayed.
The question now is whether I am executing the call incorrectly or whether there is possibly an error.
Has anyone else already had this problem?
Here is my code to create the client scope:
List<ProtocolMapper> protocolMappers = [];
ProtocolMapper mapper = new() { Name = myName, Protocol = "opernid-connect", _ProtocolMapper = "oidc-hardcoded-claim-mapper", ConsentRequired = false };
Dictionary<string, string> mapperConfig = new()
{
{ "access.token.claim", "true" },
{ "claim.name", myName},
{ "claim.value", myId},
{ "id.token.claim", "true"},
{ "userinfo.token.claim", "true"},
{ "access.tokenResponse.claim", "false"}
};
mapper.Config = mapperConfig;
protocolMappers.Add(mapper);
clientScope = new()
{
Name = newName,
Protocol = "opernid-connect",
ProtocolMappers = protocolMappers,
};
await KeycloakClient.CreateClientScopeAsync(Realm, clientScope, cancellationToken);
Hello
As far as I see both original repo and this fork are creating access token each time Keycloak API is invoked.
Can you please explain if it is possible to cache token somehow and refresh when token is expired to reduce Keycloak API load.
When using CreateProtocolMapperAsync. You have to define Keycloak.Net.Models.ProtocolMappers.ProtocolMapper with Keycloak.Net.Models.ProtocolMappers.Config which also has the wrong jsonproperties: [JsonProperty("jsonTypelabel")].
Should the attributes corrected or also a switsch to Dictionary<string,string>.
I could prepare the changes.
Add the ability to inject an HttpClient instance. This library is a no-go for my team without this capability.
Is there a way I could convince you to also implement interfaces for the keycloak client since we have a need to write unit tests against a class that is using the keycloak client but we cant mock it for various reasons and having interfaces would make things much easier for us and I should think quite a number of other people.
Discussed in #3
Bro could you please provide a documentation or leave a link blow this issue?
Hi,
in Keycloak.Net.Core/Clients/KeycloakClient.cs (and elsewhere where client info is required), there are methods that take string clientId
as an input parameter to generate URLs to /admin/realms/{realm}/clients/...
. For example, GetClientAsync, UpdateClientAsync, etc.
However, looking at the documentation of Keycloak, the API wants the Id
property of Client, not ClientId
. Because the parameter gets pasted into an URL, your code still works as long as the Id is supplied in the call, obviously, but the name of the parameter is misleading. Using ClientId
in place of Id
gets rejected with 400 Bad Request by the API (and Keycloak's own frontend uses the Id in the relevant links, as well).
Is the name of the parameter deliberate? It's very easy to confuse it with Client.ClientId
.
Consider eliminating dependency on Flurl. Flurl is a lot of complexity and cruft that adds needless overhead.
@AnderssonPeter, @campbellwray @BonnieSilentPartner , Can you variabilize the value of the key grant_type in Keycloak.Net/src/Keycloak.Net.Core/Client/KeycloakClient.cs
line 308 please ?
Something like this :
public async Task<IEnumerable<Resource>> GetResourcesOwnedByClientAsync(string realm, string clientId, string grantType) => await GetBaseUrl(realm)
.AppendPathSegment($"/realms/{realm}/protocol/openid-connect/token")
.PostUrlEncodedAsync(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", grantType),
new KeyValuePair<string, string>("response_mode", "permissions"),
new KeyValuePair<string, string>("audience", clientId)
})
.ReceiveJson<IEnumerable<Resource>>()
.ConfigureAwait(false);
Thank you ๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.