OAuth2: What exactly is the "client" - oauth-2.0

In the context of OAuth2, I would like to know exactly which component(s) of my application is considered to be the "client".
Below are the relevant exerts from rfc6749
section 1.1:
client
An application making protected resource requests on behalf of the resource owner and with its authorization. The term "client" does not imply any particular implementation characteristics (e.g., whether the application executes on a server, a desktop, or other devices).
section 2.1:
A client may be implemented as a distributed set of components, each with a different client type and security context (e.g., a distributed client with both a confidential server-based component and a public browser-based component). If the authorization server does not provide support for such clients or does not provide guidance with regard to their registration, the client SHOULD register each component as a separate client.
Scenario 1:
My application (A) consists of a browser-based front-end (component A1) and a back-end API (component A2).
The back-end (A2) acquires an access token (Authorization Code Grant) from Google's authorization server (G1) in order to access Google's resource server (G2)
Which of the following statements is/are correct?
"client" refers to (A). (A) is confidential and consists of a public component (A1) and a confidential component (A2).
"client" refers to (A2). (A2) is a confidential client.
It is incorrect to refer to (A1) as a client since (A1) doesn't make protected resource requests to (G2).
Scenario 2:
My application (A) consists of a browser-based front-end (component A1) and a back-end API (component A2).
The browser-based front-end (A1) acquires an access token (Implicit Grant) from Google's authorization server (G1) in order to access Google's resource server (G2)
Which of the following statements is/are correct?
"client" refers to (A). (A) is a public client and consists of a public component (A1) and a confidential component (A2).
"client" refers to (A1). (A1) is a public client.
It is incorrect to refer to (A2) as a client since (A2) doesn't make protected resource requests to (G2).

In scenario 1, component A1 is not the client as it does not access protected resources from Google. But component A2 is the client. And it is a protected client as it does not expose client credentials to resource owner (simply the application user). From your end point, both A1 and A2 is a single entity (a single application). But this is not the case for authorization server.
In scenario 2, component A1 obtain tokens and it consume the Google resources as well. So, from authorization server perspective, A1 is the client. And it is a public client as it cannot protect client credentials if any (it's browser based.!). Like before, from your end, A1 and A2 is a single entity.
Now think about a scenario where you need to consume Google services from both A1 and A2 components. Now you have the option to register two clients because from authorization server perspective, it see two different entities. One can protect credentials and other cannot. By doing so you fully utilise OAuth client types. To do this, auth. server may facilitate some features (which I'm also not fully aware). It could be something like ability to register two redirect URLs per one client. Or to use same client identity for confidential and public client.

Related

Distinguishing between machines with client credentials flow

It seemed like client_credentials flow was appropriate for a machine-to-machine communication between our system and third parties for importing and exporting data.
But if I have two third parties p and q say and users on our system u and v say, then I need to know which of p and q can acces the data of which of u and v.
For example: user u grants access to p (but not to q) and v to q (but not p).
I can give different client secrets to p and q but when they present thir secret to IdentityServer in order to obtain a token I need to know which of p and q it is and add a claim to the token that my controllers can use to determine which of u ad v's data is visible.
I can implement ICustomTokenRequestValidator to intercept the secret and look it up in the configuration context, but the Id column is not in the model class, so I could abuse the Description column as a foreign key to my table of third parties -- seems hacky.
Is there a standard/recommended way to resolve this situation -- that different machines have different data visible to them (different claims in their token)?
If you use client_credentials flow then there is no user-interaction involved.
Each third party should have it's own client with corresponding client credentials. Do not share the same credentials over boundaries, i.e. between different third parties. By having separate clients for separate parties, you minimize the security risk and minimize the impact when having to revoke or change the credentials.
With that said, in the Client Credentials flow the Authorization Server returns a token if the request is valid - it does not know from the request if the user authorized the request or not because the user is not involved. But it authenticates the client. So, if you want to differentiate between several third parties, give them individual clients. If you can't add a claim to the token.
Scopes and claims are the tools to define what a client requests to do. Some authorization can be done in the Authorization Server. For example, an Authorization Server typically only allows a client to request certain scopes.
Use then claims (the data in the token) for a fine grained authorization in the API. It depends on your use case. If the API is supposed to return a filtered result, i.e. only return data from users that are ok with it, then the API needs to be able to look this information up somewhere, as #gary-archer states. Use an applicable claim from the token that enables the API to identify the client or third party. It can then use this data for the lookup. For example, use the client_id claim but it really depends on the Authorization Server which claims it adds to the token.
If the client already knows beforehand which user's data it is going to access, it could add the user-id when requesting the token and - once again - depending on the capabilities of the Authorization Server - get a token with a user_id in the claim set. Then the API can use the client_id and user_id for a lookup.
How you collect the users' consent is out of scope and happens out of bound. It's part of your business logic.
At the end it is all about designing the token. Here is another article on Centralizing Identity Data
The standard option here is to include custom claims from your business data at the time of token issuance. Rather than machine to machine I would describe your scenario as B2B.
EXAMPLE USE CASE
Consider an API called by business partners who act as suppliers of inventory to your system. In this case a useful access token might look like this, and is what I would aim for:
{
client_id: 1hvf367g
supplier_id: 42
exp: ...
}
API requests for stock items could then authorize based on the supplier_id value in the access token. Eg by running a SQL query on the business data, filtering on the supplier ID. All of this keeps your API code simple.
DATA MAPPING
For this to work you need to design onboarding. Eg a button click to create a supplier in your system might create the OAuth client using Identity Server, then save the client_id to a suppliers table in the business data.
Not all identity systems support issuing custom claims in the above manner. An alternative design is to just include the client_id in the access token, and look up the supplier ID from business data when your API receives an access token. This tends to add complexity to API code though.
SUMMARY
I think your question is really about designing business permissions, and OAuth alone cannot solve it. If I'm right then the Claims Best Practices article may be useful.

OAuth2: Client Credentials flow

Problem: I am currently working on making a REST Api available to clients (the client in this case is not the normal end user who orders the articles, but the client's Web Api that communicates with my system). In order to order different products in my system, each customer may have several accounts for each country separately. Authentication is done by authenticating the client's WebApi application to my system (machine to machine). So it looks like this should be done using OAuth2 Client Credentials Flow based on the article https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-flows-app-scenarios#scenarios- and-supported-authentication-flows, but I have doubts about the issue of client accounts for each country separately.
Question: This should be solved by creating a ClientId and ClientSecret for each client account per country separately or, however, one client account should be created, while the country should be sent by the client in each request to the Api or before adding the country as a scope or claim to access token.
Additionally, I am not sure if Client Credentials Flow is a good choice in this situation, so I would be very grateful for any suggestions.
CLIENTS
Ideally each client company should have a single client credential for getting access tokens. In sone cases, such as when there are different legal subdivisions, this can be extended. By default use a single value, but you need to understand your clients.
A client credentials flow between companies can involve stronger credentials if needed, such as JWT client assertions or Mutual TLS - as in this advanced tutorial.
CLAIMS
In your system you should map domain specific data needed for authorization against each client ID. This might include country specific access to products or whatever makes sense for your scenario.
This data can then be either included in access tokens at the time of issuance, or looked up when an access token is first received, then cached for subsequent requests with the same token. Step 3 of my Authorization Blog Post explains a couple of design patterns here.
API REQUESTS
How the client gets data in API requests is interesting:
Is data for all countries owned by the caller? If so let them select the data they want via a country parameter during API requests.
If the API client shoild never be able to see data for a country, that suggests that in at least some cases you need different clients per country.
SUMMARY
Define clients in terms of what makes sense for those companies. Avoid an explosion of clients in order to manage access rights for the same data owner. Exact solutions depend on your domain specific requirements. OAuth is a framework that is meant to be adapted.
If your entire existing data-model silos 'countries' by a concept of an account, then a set of credentials per account might be the easiest.
But it sounds to me that your data-model doesn't fully capture your actual business well. It sounds to me like you have a concept of a 'customer/client' that has access to one of more 'accounts', each representing a country.
So a more correct way to model this might be to structure your API so that a single API client can access all of the related accounts, and your API should perhaps be structured so that the idea of an accountId is somehow passed (usually in the URL for REST apis). For example, each API endpoint can be prefixed with /account/123.
To me this is more of a data-modelling and API architecture question than anything OAuth2-specific.

Difference between resource and client in OAuth2

I'm developing an authentication/authorization system in Node Js for a microservice based application.
I read some articles and documentation about the OAuth2 standard but I need some clarification for my use case.
Basically OAuth2 has some actors like:
Resource owner (user)
Client app (a web application in some OAuth2 grant flows like authorization code, implicit, password)
Authorization server
Resource server (service I want to access to)
So in my database I store a client (web application) with its client_id and client_secret.
Let's suppose that one of my microservice needs to access data from another microservice. Both of them espose a REST Api.
There is no interaction with user, all is done in the background. In this case I would use the client credential flow.
Following OAuth2 rules, both of them are resource servers but in the same time it looks like they are client apps as well.
So should I register them in the client DB table/collection with client id, secret etcetera or did I make some mistakes?
Thank you
If I understood your question correctly, the caller micro-service is your client and the one that is being called is your resource. A lot depends on what type of micro-service communication pattern have you implemented. If you are implementing an "API Gateway" pattern, then your Gateway is always client and all other micro-services can be treated as resources. But if your micro-services can call each other then like you mentioned each one of them have to be registered as client and resource at the same time.

How is the correct way to add specific information for Resource Server inside OAuth2 access token?

I have a scenario where my Resource Server (RS) can connect to multiple databases and it can be multi-tenant. It has an environment configuration where I can say: Env A points to database A and belongs to tenant A; Env B points to database B and belongs to tenant B;
Our desktop apps store that information in a data structure that is sent to RS on every call and our web apps store it inside ASP.NET Session. The user select the environment at login.
Now we are moving our APIs completely to REST services and protecting them with oAuth2 using IdentityServer4.
I need to send that environment value to the APIs and I think that should be part of the access token.
The first question is: Is that correct? Can a access token have that kind of information?
The second is: Which is the best IdentityServer4 service that I should extend to inject that value as a claim inside access token and consequently inside ClaimsPrincipal.
The third is: Sometimes I don't have a user to select the environment at login (client credentials grant, for example). In this case, is the correct treat environment as a client claim? There is a way to have dynamic client claims?
Sorry about the long question!
Regards,
Diogo
If that claim is about the users (or clients) identity - yes - it is a candidate for the token.
Add the claim to the resource scopes that represent your API - this way the claim type will be requested in the profile service and you can add it to the token.
Client claims are not dynamic though.

OAuth 2.0 with complex or fine-grained scopes

I am currently working on an OAuth2 implementation for all the clients (web and mobile). So far nothing fancy about it, but we want to have more complexity in the scope, so that we can grant partial access to certain objects down to the granularity of a single property.
Example: Client gets access for a resource, let's say a user object with all its common properties. The client has full read access, but is only allowed to edit certain properties, e.g. password and username, but not location and/or birthday.
So far my thoughts are, that this granularity is defined at the Authorization Server and just interpreted by the Resource Server.
Based on the RFC the scope is a string based comma separated value, so a plain list (https://www.rfc-editor.org/rfc/rfc6749#page-23)
The value of the scope parameter is expressed as a list of space-
delimited, case-sensitive strings. The strings are defined by the
authorization server. If the value contains multiple space-delimited
strings, their order does not matter, and each string adds an
additional access range to the requested scope.
scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
So my first assumption providing json as the scope may not work, so I thought about introducing namespaces which might get to complex, e.g. (scope: user-write-full-read-list of properties or something similar).
Is there any best practice, am I missing something in the RFC or am I abusing OAuth completely?
You may want to consider the UMA protocol. The UMA RPT token is presented by the client to the Resource Server. The RPT token is issued by the Authorization Server (AS) with certain scopes. On the AS, scopes map to policies, such as who can get to what API's using which clients, network, required crypto, time of day, etc. These policies may be expressed in code or a more structured policy syntax like XACML, such as David suggested above.
If you want to learn more about UMA, I would start with this diagram:
In this case, there are two OAuth2 clients: the Resource Server (the thing with the APIs) and the Requesting Party (either a mobile application or web site).
The PAT and the AAT are normally OpenID Connect client tokens. The UMA Core spec says "OAuth2", but the only profile of OAuth2 for crypto client registration is OpenID Connect, so its implicit.
The Resource Owner is the one who makes the policies. These policies can be algorithmic or may require action by the Resource Owner. For more information about OpenID Connect, see
OpenID Connect Website
For more information about UMA see:
UMA Website
If you are looking for a free open source OAuth2 authorization server, you should take a look at the Gluu Server, which is an OpenID Connect Provider and an UMA Authorization Server for FOSS Access Management
You're abusing OAuth here. Scopes are meant to define basic permissions but not fine grained access rights let alone authorization policies.
You should use XACML for that. In XACML, you also have the notion of an authorization server (the policy decision point or pdp). It's configured using policies. It sits in the infrastructure. It is queried at runtime by the policy enforcement point which protects your api/app.
Check out developers.axiomatics.com for details (disclaimer: I work for Axiomatics)

Resources