How can I set Keycloak user id as static? - keycloak

I am using Keycloak for authentication.
I used the user id in the access token as a user identity and stored it in some tables when users did some actions. I have some counters relying on user-id.
But recently, I found that the Keycloak user id is dynamic and it is changed after some time(I am not sure how long a user-id is kept) that making my counters counted improperly.
So I wonder is there a way that we set the user id static? And how can I get the user email from the user-id that had been changed in the past?
I am really appreciated your help and suggestions. Thank you so much.

I am not 100 % sure about:
But recently, I found that the Keycloak user id is dynamic and it is
changed after some time( I am not sure how long a user-id is kept)
that making my counters counted improperly.
You can use the claim sub in combination with a public subject identifier types. Have a look a this answer for a more detailed explanation.

Answer: it was my mistake. I used two accounts with the same username and different email IDs. When I ran the query with username filter, it returned 2 user id. That's why I think the user id generated by Keycloak is dynamic.
Confirm again: the user-id is fixed.

Related

Keycloak - user attributes that are specific to groups

I'm using Keycloak as an identity provider in my app. However, I could not find anywhere how to give a user an attribute whose value would be specific to a group. For example : a role within the group ("user", "admin"...), a “pending invitation” status, etc.
Is this even possible, or should I make an external table in my database, mapping user ids with group ids and adding the other attributes ? This additionnal table would be bothersome in terms of architecture.
Have a great day !
Antoine
Keycloak doesn't support assigning attributes/roles with the group scope. It only supports having roles that are "client" specific. As you mentioned yourself, you have to implement a custom provider and persist them in your own storage.
You can set user's attribute with role name/id and status.
This API call can do
PUT {Keycloak URL}/auth/admin/realms/{realm-name}/users/{user-id} OR
PUT {Keycloak URL}/admin/realms/{realm-name}/users/{user-id}
it depends on you Keycloak verion.
And Get user's value by this API
GET {Keycloak URL}/auth/admin/realms/{realm-name}/users/?username={user-name} OR
GET {Keycloak URL}/admin/realms/{realm-name}/users/?username={user-name}
This demo by Postman.
Set user's attributes
Get user's attributes
Get token and set token reference this answer part.
here

Naming REST API of user details informations

Suppose you have 2 relational tables: User and UserDetails.
In the user table you store userId, password, email ecc.
In the UserDetails table you store other info user-related, such as user preferences, last time logged, last IP ecc. Between User and UserDetails exist a 1-1 relationship, they share the same primary key (userId).
How do you name your REST API to retrieve UserDetails info of a specific user? Is /users/userId/userdetail correct or can you suggest a better API name?
There is no right or wrong way for naming API endpoints. It is best just to be consistent within your application. Since you have two tables with the same id, I might make the endpoint userdetails/{userId} to get the information from the UserDetail table. Then you could have a similar enpoint users/{userId} to get the information from the User table. But again, what you have is perfectly acceptable.
Here is an article that lays some of the best practices for naming API endpoints that I found useful: https://restfulapi.net/resource-naming/
Hopefully that helps!

Bigcommerce API Authenticating a customer with GET request

I'm doing a GET for customers with a given email address (there will only be one). Before displaying the returned information, I need to authenticate the user, but I can't see a way in the docs that allows providing a password as a parameter to a GET. In fact It only seems to be possible to provide a password when creating (POSTing) or updating (PUTting) a customer. Is it possible to authenticate customers via the API this way?
from what I understand - _authentication is only supported for POST and PUT on customer objects. I believe it is intended to create a customer who can login and stuff like that.
Can you explain your use case and maybe there is a workaround..

Representation of a User in REST

I'm slowly beginning to unerstand REST and theres one thing thats confusing me .
I understand that most of the things in REST is a "resource" . So i was wondering what kind of a resource would we be referring to in the case of a user signup / login ?
Is it users ? Then does it mean that a POST on users would signup for a new user . If that is the case , then how do i authenticate a user ? a GET on users with an encoded password / username pair?
I'm really confused with this.
I may be COMPLETELY wrong in my understanding given that i'm just starting to understand REST.
Any help is appreciated !
Thanks!
It's a bit of an unusual but common problem for REST. Keep thinking about resources.
When you login you're asking the server to create a session for you to access certain resources. So in this case the resource to create would be a session. So perhaps the url would be /api/sessions and a POST to that url with a session object (which could just be an object consisting of a username or password and perhaps the UUID) would create a session. In true REST you'd probably point to a new session at /api/sessions/{UUID} but in reality (and for security purposes) you'd probably just register a session cookie.
That's my own personal approach to login forms if I were to implement them myself but I always tend to use Spring security for that job so this requirement never really takes much consideration.
I am working on something similar and this is the solution I have taken so far. Any suggestions welcome :)
I have users exclusively for singup and account modifications.
GET /users/{id} gets a user for the profile page for instance
PUT /users creates a new user with username and password. In reality this should send an email with a link to somewhere that confirms the signup with a GET method.
POST /users/{id} modifies the user (for example change password)
DELETE /users/{id}
For authentication I tend to think that the resource I request is the token or the authentication. I have tried to avoid the word "session" because it is supposed to be anti-RESTful, but if you are just creating the illusion of an actual server-side session for your clients, I guess it is fine.
PUT /authentication/ with usename/password returns Set-Cookie with the pair user_id / hashed value. Maybe it should be POST. Not sure
DELETE /authentication/{user_id} just deletes the cookie and the user is signed out. Maybe instead of user_id it should be a unique token_id.
Resources can be created, read, update and deleted using a restful approach, see e.g.:
https://cwiki.apache.org/S2PLUGINS/restful-crud-for-html-methods.html
So if you'd like to administrate you users this would be the restful approach to do so.
If you'd like to authenticate the users which you have in your administration dataset you need
to design or select a restful authentication mechanism see e.g.
http://de.slideshare.net/sullis/oauth-and-rest-web-services
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
For a jumpstart on these issues you might want to check out dropwizard:
http://dropwizard.codahale.com/
A resource may have one URI or many
but One URI will have exactly one Resource
Therefore, When Authenticating a user, you are addressing a user who is already registered
While when registering, you are addressing the user (resource) which is yet to be registered.
All you need is a way to process it to your SERVER.
THIS is an example taken from SUGARCRM REST web services implementation.
REST is like http requests to your SERVER.
For eg, when implementing REST Web Services.
Every REST Request is going to same File say
www.your_domain.com/Rest.php?json={your_json_method:'method',params:'watever'}
Where in Json is the request you are sending as a parameters
Requesting to authenticate a user
{method:'SignUp', username:'abc', pass:'pass', confirm_pass:'pass'}
Requesting to register a user
{method:'Login', username:'abc', pass:'pass'}
by this way you can have as many params as you want
Remember JSON is not necessory to be used. you can use simple get params for your query

Restful Api: User id in each repository method?

I am new to both .Net & RESTful services.
Here is the object hierarchy I have in the database: Users->Folders->Notes.
The API: GET /api/note/{noteid}
would get mapped to the repository call
NoteRepository::GetNote(userId, noteId)
Notice that I am passing on the userId to make sure that the note belongs to the logged in user for security purpose.
Is this the right approach? Meaning, every repository call would have the first parameter as the userId to check if the object being accessed belongs to the user.
Is there any better approach?
You don't need the User Id since the
GET /api/note/{noteid}
is indeed unique.
A valid scenario for adding the id would be:
GET /api/{userId}/notes
And then if you want a specific note you can:
GET /api/{userId}/notes/{noteId}
I would implement security at the entry level. whether the user has rights to perform a method on that specific resource. A role model approach would be fine.
Regards.
I would also introduce the user id in the API, because of Stateless and Cacheable constraints described in the Wikipedia REST article.
However, if I check Google Tasks REST API, they don't include the user id, same thing for Twitter API, so it seems a trend not to include the user id. If someone can shed some light I would be grateful.
UPDATE: Thinking more about it, if the noteid is unique across all users, there is no need to include the user id, so a GET /api/note/{noteid} is fine.
However, the logical parent in a restful interface would be GET /api/note/ to get a list of all notes, and here I've the objection, since the list would differ according to the user requesting it, making it non cacheable.
As for your dot net part I think that passing the userid among dot net methods is perfectly fine.