I have a resource server and a few clients implementing Oauth2 security.
The flow I'm using is (I don't know the correct name):
1) The resource owner try to access a web application (client and resource server).
2) This web application can't even show the index page so the resource owner is redirected
to the OAuth2 (Authorization) server passing a client_id and a password in a Basic Auth POST.
3) The Authorization server show a login page and the user enter the username and password.
4) The Authorization server send the user back to the web application and he can
access the resources (web pages).
I have a database with some tables.
All is working very very fine. What I need? There is no logical relationship between oauth_client_details (the applications table) and users so any registered user can access any registered client.
I need to restrict a user to access only the applications I choose.
Bonus: Can someone tell me the correct OAuth flow name I'm using?
Unfortunately your description of the flow doesn't fully match with any flows defined by OAuth 2 specification.
HTTP POST for authorization request is valid by the OAuth 2.0 protocol. But I haven't seen sending client credentials in an authorization request.
Closest I can guess this to be Client Credentials Grant but again step 3 is not there in this flow. So I think you are using a flow that is defined by your organisation.
Now when it comes to client application associations to end users, I think you need another table which store client applications and user identifiers mapping. Your OAuth server must only issue tokens if requesting client application is enabled to an specific end user identity. I'm not a database expert but tables would look like below
**Oauth_cliet_details_tab**
---------------------------------------------------
| Client_ID | Client_Secret | Redirect_URL | etc..|
---------------------------------------------------
**Users_tab**
--------------------------------------------------------
|User_ID | User_Name | Email | Hashed_Salted_PWD| etc...
--------------------------------------------------------
And now your client application permission tab should look like
**User_client_permisison_tab**
----------------------
|User_ID | Client_ID |
----------------------
Note that UserID is a foreign key from Users_tab and Client_ID is a foreign key from Oauth_cliet_details_tab. Both User_ID and Client_ID create a composite primary key.
So when your OAuth server get a request, you must validate client credentials, end user credentials and then using client id and end user id, you must check this table for existing record to allow tokens to be issued. You have to somehow add and remove entries from this table and that could be a configuration step.
Related
My understanding of an Oauth2.0 Server is that it grants clients access to resources when the resource owner has granted permission to a client. So say I have a user Bob and he's given permission to two clients (client1, client2) to access his stuff. As part of that Bob logs in 2x. Once like so:
http://10.234.233.23:9081/oauth/authorize?client_id=client1&response_type=code&scope=all
and he gets an auth-code -> FIbSqy
and again like so for the second client
http://10.234.233.23:9081/oauth/authorize?client_id=client2&response_type=code&scope=all
and again he gets a second auth-code -> h4ckJQ
He hands those auth-codes off to app1 and app2 respectively. Then those clients log into the oauth server and exchange those auth-codes for tokens. Then ever after the tokens are used to make calls and get resources.
My question is how the heck do you authenticate two clients at once on the auth server when the auth server appears to cache the first person's credentials and then never lets anyone else login.
Because for me the first client to exchange an auth code for a token...gets tokens and every other sorry client afterwards gets the following error:
I know you can register clients...and I have them all registered with the outh server...but is there also a "login" url that I'm missing that lets them all login at the same time?
OAuth supports state. This is recommended to prevent cross-site request forgery. This state can be used to support multiple logins simultaneously.
http://10.234.233.23:9081/oauth/authorize?client_id=client1&response_type=code&scope=all&state=some-big-random-number-string
I am working on an application in which users with elevated roles (administrators) can create other users (with lower roles). I'm using PHP (Slim framework) and MySQL.
So far i have a Resource Server which can be accessed through a REST API with access tokens obtained from the OAuth Server using the Password Grant. The two servers have separate databases. There is also a Web Server which provides a dashboard where administrators log in and create new users by setting their username, password and other generic information.
Considering the fact that both the Resource Server and the OAuth Server have to store user data in their respective db tables, would it be ok if the Resource Server, upon a new user request, stores the generic user info in it's "users" table AND sends a request with the user credentials to the OAuth Server which will add a new entry in it's "oauth_users" table ? If not, what would be the best and secure way to achieve this functionality ?
Thank you in advance!
This approach works for us.
On the Auth Server db side you have to store only: user id, redirect url's and authorized service level (scopes) configured; the access tokens granted; and other authorization required data (roles in your case).
The Login Server db, stores: user id, password and other authentication related data.
The User resource service (commonly a RESTFul API) should store: user id and other personal data.
Upon a new user request of a secured resource data (some scope is needed here), redirects to the Login Server, with this successful authentication, redirects to the Auth Server to grant permissions using that scope, generate an access token and redirect to the secured resource with an access token, the resource server validates the token and the scope (some implementations also make another call to the Auth Server to validate this using JWT) to finally allow the initial user request.
In general, I personally use the DRY principle with this kind of architecture.
Cheers!
I am using Identity Server 4 for authenticate user from a single application page. For the need of the project, I have to use the resource owner password flow.
Identity Server and my application work fine together. Identity Server give an Access Token and I can use this token to access some API that we own.
However, I was asking myself about the Access Token, users and socpes. For now my setup is this one.
I have an API that require the scope API-1.
I have a client (my SPA) where I defined the scope API-1
And I have a user.
In this configuration, it is the client who own the right to access the API, not the user. And I'm wondering how to give this scope to the user and not anymore to the client.
Stupidly, I'm wondering if user can own the scope and not the client. Maybe I've miss or misunderstood something, so please teach me.
In the Resource Owner Password Flow your client will always need to have permission to the scope that your resource is protected by. This does not mean that you cannot protect your API based on claims related to the user however.
If in your API for example you need different permissions based on the user accessing the API look to use the claims information as part of your authorization. In the Resource Owner Password Flow example at http://docs.identityserver.io/en/release/quickstarts/2_resource_owner_passwords.html you will see that it mentions this at the foot of the page, see the two paragraphs as follows:
When you send the token to the identity API endpoint, you will notice one small but important difference compared to the client credentials grant. The access token will now contain a sub claim which uniquely identifies the user. This “sub” claim can be seen by examining the content variable after the call to the API and also will be displayed on the screen by the console application.
The presence (or absence) of the sub claim let’s the API distinguish between calls on behalf of clients and calls on behalf of users.
I would like to provide some standarized SSO mechanism in my application (some different clients, growing number of services in the backend). I am wondering if OIDC/OAuth 2 is the right tool for it.
In all examples I have seen, end user is the Resource Owner and it grants permissions (or not) to some external apps by redidericting to a page asking for permissions.
My use case is different, I want to use OAuth inside my system (for apis, web pages etc.): resource owner is i.e. some service with database (plus administrator who have access to it), end user tries to get some resources from the system. User cannot grant anything, he can be granted. I think it's the most classic scenario, which can be named Single-Sign-On. Is there any standard flow for this in OAuth 2 (or preferably OpenId Connect)? Is it achievable? Or am I looking at a wrong tool?
OIDC/OAuth can be used for both consumer as well as enterprise scenario's. The consent steps of OAuth are useful in consumer oriented scenario's. When dealing with enterprise scenario's like yours, there's no point in asking consent since it is implicit, at least for the enterprise's apps. That is certainly covered by OAuth/OIDC: the Authorization Server is not required to ask for consent and can (typically) be configured to skip that step for particular Clients. So: using OpenID Connect without consent would be suitable.
For your usecase you can use combination of OpenID Connect and OAuth Client_Creds flow. For example suppose you have a HRMS application which needs to get the employee data to show to the employee from some DB.
Register HRMS with OPenID Provider
Register HRMS as Client to OAuth Server (OpenID Server and OAuth Server can be same)
When User comes to HRMS application:
a. Check for Id_token cookie, if not present then redirect to IDP
b. IDP authenticates and if successful redirects back to SP with ID token
c. If token is valid then SP sets the token as cookie in the browser using another redirect to itself but to the home page
Now All processing will be server side:
a. HRMS app hits the IDP to get the User Data
b. If successful then it hits the OAuth Server to get the access_token
c. if successful then it uses the access_token to talk to DB Service and
get the data
SP=Service Provider, IDP = Identity Provider
Actual flow can be a little different based on security considerations.
Hope this makes it helps.
The difference between the "Resource Owner Password Flow" and the "Client Credentials Flow" seems unclear to me. The former seems to forward the password credentials to the server for verification, while the latter does authenticate with the server in some way too, but the spec doesn't specify what method is used here. Is this flow designed for cookie sessions? The spec doesn't really provide a clear use case.
From the OAuth 2.0 spec:
+---------+ +---------------+
| | | |
| |>--(A)- Client Authentication --->| Authorization |
| Client | | Server |
| |<--(B)---- Access Token ---------<| |
| | | |
+---------+ +---------------+
Figure 6: Client Credentials Flow
and
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
Figure 5: Resource Owner Password Credentials Flow
The client credentials flow only requires the client_id and client_secret. The Resource Owner flow requires the user's password.
The client credentials flow allows an application to get a token w/out the context of the user.
A good example of this would be the following:
Suppose you're a statistics company called AllStats that has its own user base where each user has their own username and password. AllStats has its own existing website which dogfoods its own API. However, AllStats now wants to release a mobile app.
Since the mobile app will be a 1st party application (see: developed by AllStats), the Resource Owner Password Flow makes a lot of sense. You'll want the user to get a screen (username, password) that flows with the app instead of kicking them over to an auth server (and then back into the app). Users will trust the application when they enter their username/password because it's a 1st party app.
I like to look at the Resource Owner Password Flow as a flow that 1st party app developers would use, whereas the Client Credentials Flow a flow that 3rd party app developers would use.
Imagine if the Facebook app required you to use the Client Credentials Flow instead of just presenting you with a username/password form. Would seem a little odd, yeah?
Now, if imagine you download a 3rd party app that had Facebook integration. I'd imagine you (and most people) would be very leery if the app was prompting you for a username/password instead of using the Client Credential Flow UI.
FWIW, this isn't to say that 1st party apps don't use the Client Credential Flow. But rather to try and paint a real world scenario (and overall generalization) of when Resource Owner Password Flow would be used.
Besides user3287829's answer. I want to add the following.
As the RFC said about Client Credential grant.
The client makes a request to the token endpoint by adding the
following parameters using the "application/x-www-form-urlencoded"
format per Appendix B with a character encoding of UTF-8 in the HTTP
request entity-body:
grant_type
REQUIRED. Value MUST be set to "client_credentials".
scope
OPTIONAL. The scope of the access request as described by
Section 3.3.
The client MUST authenticate with the authorization server as
described in Section 3.2.1.
For example, the client makes the following HTTP request using
transport-layer security (with extra line breaks for display purposes
only):
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
The authorization server MUST authenticate the client.
The client must be registered in the authorization server in advance. and Authorization includes the client credential which will be authenticated by the server.
This is the closest answer to the question. However, none of the answers provide a clearer example:
You must use the Client Credentials Grant when a machine needs access to resources it owns on another machine.
It is necessary to use the Resource Owner Password Credentials Grant (actually not, it is better to use the Authorization Code Grant) when the machine needs to access resources that belong to the end user (not the machine) on behalf of that user.
The key question you should ask yourself when choosing between these two flows is who owns the resource to be accessed. If it belongs to the machine (client), then you need the first option, if it does not belong to the machine, but belongs to the user on whose behalf the machine will execute requests, then you need the second option.
Other answers explain well about the "Resource Owner Password Flow". So I will explain the "Client_credentials" grant type flow. In the "Client_credentials" flow client_id and client_secret are used to authenticate the Client not the Resource owner. So you can ask without the Resource owner authentication how a client (Most of the time a application) will obtain access to the resources. That's a good question. The answer is, here Client will get access_token for it's own resources or access to an user-resource which is already given under this client_id. client_secret and client_id generation is a most of the time a manual process. For example look at this -> Create a client ID and client secret for google APIs. In the Client secret creation step you are creating authentication credential for your application.
additionally, in terms of auditing, resource owner is better way, because you can identify by access_token which specific user is calling your api through the client application, while client_credential identifies only the application client