Well, the title speaks for itself. In many places from Keycloak docs I encountered this statement
id of client (not client-id)
For now this statement sounds so stupid to me as I do not understand the difference between client-id and id of the client. Can somebody explain me this, please?
When you're creating a new client, you specify its Client ID (or simply client's name), e.g. "my-super-client". This is supposed to be unique across the realm and usually used in OAuth calls, e.g. as a client_id in "Client Credentials" flow (in pair with client_secret).
However, when creating a new client, KeyCloak issues an internal unique ID like this 3f7dd007-568f-4f4a-bbac-2e6bfff93860. You may find it in a URL when opening a page of your "my-super-client" in the web interface. This one is supposed to be a unique ID of any resource that KeyCloak creates during its lifespan.
Keeping this in mind, I think it'd be clear from the context of documentation which one is "id of client" and which one is "client-id" as you stated in the question. If not, please give a link here.
Related
Say I'm creating a journaling application and I want users to be able to post entries to their journals.
I do not intend to ever allow a user (even a moderator) to post an entry in someone else's journal.
That said, are there any arguments for exposing the account or journal id in my endpoint path?
I would think that POST api/journals/postEntry would be sufficient as I can determine the user via access token or JWT token.
Can anyone think of arguments for providing the journalId in the path? EX: POST api/journals/{user journalId}/postEntry
Can anyone think of arguments for providing the journalId in the path? EX: POST api/journals/{user journalId}/postEntry
Short answer: it's a violation of the uniform interface constraint.
See Fielding, 2000.
What you are doing, in effect, is creating this little corner of the world where, instead of using the target-uri to identify a resource, you are instead using target-uri + token.
Which means that your thing doesn't use the semantics that the general purpose components in the world are expecting.
For example, when I copy the URI out of my user agent, and share it with someone else, that other person doesn't get the result I expect -- they end up looking at their view, not mine.
The fact that we can stick a URI in an email message and have it just work for the person reading the email is a really big piece in the adoption story.
Furthermore, the cache constraint in REST rather depends on being able to use the identifier as the primary cache key. So your bespoke identity mechanism has the potential to mess up caching.
IN PRACTICE: you are using HTTP, and HTTP has caching rules that prohibit sharing authenticated requests. So the caching issues mentioned above are purely theoretical.
Alternatives you might consider
You could arrange for /api/journals/postEntry to redirect to /api/journals/{userJournalId}/postEntry
You could use the Content-Location header to indicate that there is a more specific identifier for the current representation.
You can use the canonical link relation to help clients navigate to the preferred resource from the alternatives.
I use an authentication service Auth0 to allow users to log into my application. The application is a Q&A platform much like stackoverflow. I store a user profile on my server with information such as: 'about me', votes, preferences, etc.
When new user signs in i need to do 1 of 2 things:
For an existing user - retrieve the user profile from my api server
For a new user - create a new profile on the database
After the user signs in, Auth0(the authentication service) will send me some details(unique id, name and email) about the user but it does not indicate whether this is a new user(a sign up) or a existing user(a sign in).
This is not a complex problem but it would be good to understand best practice. I can think of 2 less than ideal ways to deal with this:
**Solution 1 - GET request **
Send a get request to api server passing the unique id
If a record is found return it
Else create new profile on db and return the new profile
This seems incorrect because the GET request should not be writing to the server.
**Solution 2 - One GET and a conditional POST request **
Send a get request to api server passing the unique id
The server checks the db and returns the profile or an error message
If the api server returns an error message send a post request to create a new profile
Else redirect to the home page
This seems inefficient because we need 2 requests to achieve a simple result.
Can anyone shed some light on what's best practice?
There's an extra option. You can use a rule in Auth0 to send a POST to the /users/create endpoint in your API server when it's the first time the user is logging in, assuming both the user database in Auth0 and in your app are up-to-date.
It would look something like this:
[...]
var loginCount = context.stats.loginsCount;
if (loginCount == 1) {
// send POST to your API and create the user
// most likely you'll want to await for response before moving on with the login flow
}
[...]
If, on the other hand, you're referring to proper API design and how to implement a find-or-create endpoint that's RESTful, maybe this answer is useful.
There seems to be a bit of disagreement on the best approach and some interesting subtleties as discussed in this post: REST Lazy Reference Create GET or POST?
Please read the entire post but I lean towards #Cormac Mulhall and #Blake Mitchell answers:
The client wants the current state of the resource from the server. It is not aware this might mean creating a resource and it does not care one jolt that this is the first time anyone has attempted to get this resource before, nor that the server has to create the resource on its end.
The following quote from The RESTful cookbook provided by #Blake Mitchell makes a subtle distinction which also supports Mulhall's view:
What are idempotent and/or safe methods?
Safe methods are HTTP methods that do not modify resources. For instance, using GET or HEAD on a resource URL, should NEVER change the resource. However, this is not completely true. It means: it won't change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation.
Finally this key distinction is made in Section 9.1.1 of the HTTP specification:
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects,
so therefore cannot be held accountable for them.
Going back to the initial question, the above seems to support Solution 1 which is to create the profile on the server if it does not already exist.
I have some REST services on my site that will be available for 3rd parties to access.
My plan is simple. In order to call on these services, they need to request a key from me. I will privately supply them with a GUID. Each call to any of my services will, via a filter, check the header for the key and accept/reject the request accordingly.
This site is all HTTPS so the key would be encrypted during transit. I'm not worried about the key being visually identifiable to authorized clients. In other words, I'm not worried about any kind of 'inside' attacks or people sharing the key. I just don't want random, unauthorized outside users.
I have looked around and I don't really see anybody doing it exactly this way. I feel like I'm over-simplifying... but on the other hand, I don't see what's wrong with it either.
My question is.. does this sound secure enough (from a basic/minimal perspective) or does it expose some gaping security hole that I'm not seeing?
FWIW - I am using the Spring Framework, including Spring Security 4.
Thanks!
If it's HTTPS and the API key is in the header encrypted during transit as you described etc, then it follows a pretty standard design authentication pattern.
Your security now depends on how you distribute and store your API keys.
Although, you could use an "Application Identifier and Key pairs" approach.
Whereas the API Key Pattern combines the identity of the application
and the secret usage token in one token, this pattern separates the
two. Each application using the API issues an immutable initial
identifier known as the Application ID (App ID). The App ID is
constant and may or may not be secret. In addition each application
may have 1-n Application Keys (App_Keys). Each Key is associated
directly with the App_ID and should be treated as secret.
Just in case you wish to extend the application in the future.
I am at start of develoment of web-application. Application should be RESTful.
I am new to REST. And now I can't understand how user login/logout need to be done correctly to meet REST restrictions.
I spent good time to understand REST and already read many articles and answers on StackOverflow. Also I understand basic principle of "stateless" and it's benefits. So please no links on Wikipedia and basic sources about REST.
About task:
I have list of books in database on server. User who has login/password may come to site, enter login/password and view page with these books. So before to answer with list of books server need to be sure that user has rights to do it.
List of books will requested by AJAX call from browser.
I am going to make server to handle URL /books . When server receives GET request to this URL - it should
1) authenticate this call;
2) if OK - answer with list of books in JSON format.
As I understand so far - correct way of authentication for REST server is to authenticate each separate call. Client should use Secret Access Key and Access Key ID to encrypt query parameters. And server will check for Access Key ID, retrieve Secret Access Key (that is shared secret) and validate query in this way.
So server doesn't handle sessions because it violates "stateless" restriction of REST.
Only way how I see it could be done without sessions - use some Secret Access Key and Access Key ID to encrypt query parameters. This is how usual REST clients do. But there is a big difference between "normal" REST client and browser REST client.
Normal REST client (lets say it is standalone application or PHP-application on server) stores their Secret Access Key in some secure way. Nobody can see it. But JS application stores it right in code. And anybody can open this JS code and find this key.
So my question is:
How to organize authentication between browser (REST client) and server that handles REST API without exposing Secret Key to anybody who can open source code.
Or maybe I overestimate issue of storing of Secret Access Key in code?
I just see big difference with classical "stateful" application:
If I am logged in to some site and out of computer at the moment - nobody can come to computer and find my password in any place in memory of browser.
But with storing Secret Access Key in code it is possible.
Try to use the Basic authentication which works with browser based application. But problem with it is that it will always throw a pop-up to the user. An alternative to it is that you use a custom login header to do the authentication of each REST request, for example
headers : { "Authorization" : "customAuth" }
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