OAuth2 Clients and Grants - oauth-2.0

2. Client Registration says:
When registering a client, the client developer SHALL:
o specify the client type
but it is not specified how to define available grant types.
I can't understand how to define available grants for client. Can the client use all grants, several grants or only one.
2.1. Client Types spec section defines confidential (web application) and public (user-agent-based application & native application) client types. Public client can't secure any client authentication credentials, so for such clients must be available only implicit grant or may be password grant for resource owner trusted client? But i'm not found such restrictions.

Which grants are made available to Clients is a deployment decision to be made by the Authorization Server. In principle (by spec) there's no restriction on which grant types the Client can use. A typical way of working is that the administrator of the Authorization Server registers a Client and then assigns the grant types that are available to it. As you suggested, that can be just one grant, several grants or all of them (well, depending on the availability of a client secret, see below).
The Implicit grant by definition can only be used by public Clients because there is no option to authenticate itself as part of the protocol flow. Yet other grants can be made available to both public Clients as well as confidential Clients because they may be used with or without a client secret and as pointed out above it would be a deployment decision to define which Client can use which grant.
As an example of the latter: the Authorization Code grant is perfectly usable for public Clients in addition to its availability for confidential Clients. The public Client would receive an authorization code in the regular way and would present it to the token endpoint without authenticating itself as a confidential Client would do. Because it wouldn't offer any clear security benefits over the Implicit grant yet does require an extra roundtrip to the Authorization Server it is not widely deployed but it is certainly not prohibited.
The Resource Owner Password Credentials grant is another example of a grant that can be used by both confidential Clients as well as public Clients. The Client would not authenticate itself to the token endpoint but merely pass the Resource Owner password to get an access token.

Related

Is a shared secret even necessary when using RSA256 (asymmetric) signed JWT?

One often reads that the ResourceOwnerCredentials Flow is bad because there can not be a secret key involved with an untrusted client (lika a Javascript or mobile Application).
Is this even valid if the tokens are signed asymmetrically and can be validated by the client using the public key JWK (Json Web Key) provided by the OAuth 2.0 server?
You have misinterpreted the "Resource Owner Password Credentials Grant" (link to spec.).
What this flow does is, substitution resource owner's (if it's a person, it will be the end user) credentials with authorisation code. As the specification says it can be used to replace legacy systems which for example use basic authentication. And to this to be done, trust should be established between client and resource owner. Found a good article which you can read more on this link
On the other hand, Client Credentials Grant is a grant which requires client to obtain and maintain (link to spec.). And this grant is only applicable to confidential clients
The client credentials grant type MUST only be used by confidential
clients.
I believe you have confused about two different grant types. As you have already seen, mobile applications and JavaScript applications are public client. So the client credential grant cannot be used for them.
Furthermore, once can indeed validate tokens using public key but to do that one should obtain tokens by completing a valid flow.
For a confidential client, shared secret can be used to encrypt the token. But this cannot be done for a public client as they cannot maintain a shared secret.
Anyway here are use cases for using client authentication (as described in specification : Client authentication)
Enforcing the binding of refresh tokens and authorization codes to
the client they were issued to. Client authentication is critical
when an authorization code is transmitted to the redirection
endpoint over an insecure channel or when the redirection URI has
not been registered in full.
Recovering from a compromised client by disabling the client or
changing its credentials, thus preventing an attacker from abusing
stolen refresh tokens. Changing a single set of client
credentials is significantly faster than revoking an entire set of
refresh tokens.
Implementing authentication management best practices, which
require periodic credential rotation. Rotation of an entire set
of refresh tokens can be challenging, while rotation of a single
set of client credentials is significantly easier.
As a fact, confidential client allows you the flexibility of altering client authentication by changing the shared secret.

What are the limits of public clients in OAuth 2.0

OAuth 2.0 specifies two client types:
public (client_id)
confidential (client_id:client_secret)
and section 2.2 says:
The client identifier is not a
secret; it is exposed to the resource owner and MUST NOT be used
alone for client authentication.
While it is clear to me that public clients are primarily used for the implicit flow, there is more to this than it seems. When performing the auth code flow, we first request the authorization endpoint with our client_id, no secret required. Then, after getting the user's consent and the authorize code, we request the token endpoint. According to spec, we are able to request this endpoint without a client_secret:
client_id
REQUIRED, if the client is not authenticating with the
authorization server as described in Section 3.2.1.
If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.
...
The authorization server MUST:
...
o ensure that the authorization code was issued to the authenticated
confidential client, or if the client is public, ensure that the
code was issued to "client_id" in the request,
So basically this section says that we are able to request this endpoint without a client secret. Now, it doesn't say anything about refresh tokens other than that those may be included in the request.
Refreshing an access token mentions:
Because refresh tokens are typically long-lasting credentials used to
request additional access tokens, the refresh token is bound to the
client to which it was issued. If the client type is confidential or
the client was issued client credentials (or assigned other
authentication requirements), the client MUST authenticate with the
authorization server as described in Section 3.2.1.
So basically we're allowed to refresh the access token without client authentication.
Now, what confuses me is that the implicit flow does not allow issuing of refresh tokens:
The authorization server MUST NOT issue a refresh token.
It doesn't say explicitly why we can't do that, only that we're not allowed to. My reasoning is that this isn't allowed because the client can't be trusted. But since the authorize code flow is allowed for public clients, why do we actually need the implicit flow, if the same thing can be achieved with a public client, plus getting a refresh token?
I'd be very glad if someone could clarify this.
You are allowed to request/refresh access token without client secret at your own risk. Or we can say it depends on your security requirements. The spec only clarifies client authentication for confidential clients, basically if the client is confidential. it MUST be authenticated by the server.
For public clients, the spec says:
The authorization server MUST NOT issue client passwords or other
client credentials to native application or user-agent-based
application clients for the purpose of client authentication.
So public clients can't even have a secret to be authenticated with. And then the spec also says:
When client authentication is not possible, the authorization server
SHOULD employ other means to validate the client's identity -- for
example, by requiring the registration of the client redirection URI
or enlisting the resource owner to confirm identity. A valid
redirection URI is not sufficient to verify the client's identity
when asking for resource owner authorization but can be used to
prevent delivering credentials to a counterfeit client after
obtaining resource owner authorization.
Also you may look at PKCE.
Get back to your question, I think you are misunderstanding:
According to spec, we are able to request this endpoint without a client_secret.
Not quite right, you must authenticate confidential client and you can't authenticate public client using a client secret (it does not have one).
The authorization server MUST NOT issue a refresh token.
I think it is all matter of security. In implicit grant, we are operating under a presumably unsafe environment. Exposing refresh token could harm your system, since we already expose access token in this grant type (Please read security consideration for access token).
But since the authorize code flow is allowed for public clients, why do we actually need the implicit flow, if the same thing can be achieved with a public client, plus getting a refresh token?
They are meant for completely different use cases. From https://oauth.net/2/grant-types/implicit/
The Implicit grant type is a simplified flow that can be used by public clients, where the access token is returned immediately without an extra authorization code exchange step.
It is generally not recommended to use the implicit flow (and some servers prohibit this flow entirely). In the time since the spec was originally written, the industry best practice has changed to recommend that public clients should use the authorization code flow with the PKCE extension instead.
Lastly, I suggest you to play with this site to get a better understanding of different grant types.

Keycloak - OpenId Connect Access types

I'd like to authenticate a legacy java (6) application against a node-js one currently secured using keycloak OIDC bearer only (both apps belonging to same realm).
I've been told to use keycloak-authz-client library resolving a keycloak OIDC JSON as below
{
"realm": "xxx",
"realm-public-key": "fnzejhbfbhafbazhfzafazbfgeuizrgyez...",
"bearer-only": true,
"auth-server-url": "http://xxx:80/auth",
"ssl-required": "external",
"resource": "resourceName"
}
However, the keycloak java client required java 8 and my current runtime is a jre6. Recompiling the lib including transitive dependencies does not looks like a good idea and I end up so using keycloak oauth2 REST endpoint.
As far as I know oauth2 I would go with a client_credentials flows exchanging a client secret against an access_token once at application initialization and refreshing / renewing when expired.
Coming to keycloak documentation :
Access Type
This defines the type of the OIDC client.
confidential
Confidential access type is for server-side clients that need to perform a browser login and require a client secret when they turn an
access code into an access token, (see Access Token Request in the
OAuth 2.0 spec for more details). This type should be used for
server-side applications. public
Public access type is for client-side clients that need to perform a browser login. With a client-side application there is no way to
keep a secret safe. Instead it is very important to restrict access by
configuring correct redirect URIs for the client. bearer-only
Bearer-only access type means that the application only allows bearer token requests. If this is turned on, this application cannot
participate in browser logins.
It seems that confidential access type is the one suitable for my needs (should be used for server-side applications) however I don't get how it is related to browser login (which is my mind is related to authenticating using third parties identity providers as facebook and co).
The confidential client settings also require a valid redirect uri the browser will redirect to after successful login or lagout. As the client I want to authenticate is an application I don't see the point.
Generally speaking I don't get the whole access type things. Is it related only to the client or to the resource owner also (Is my node.js application stuck to bearer-only as existing clients use this access type ? will it accept the bearer authentication using the access_token obtained with client_credentials flow ? I suppose it will).
Can someone clarify keycloak OIDC access type and where I went wrong if I did ?
What is the proper way to delegate access for my legacy application to some resources (not limited to a specific user ones) of another application using keycloak ?
You are mixing up the OAuth 2.0 concepts of Client Types and Grants. Those are different, albeit interconnected, concepts. The former refers to the application architecture, whereas the latter to the appropriate grant to handle a particular Authorization/Authentication use-case.
One chooses and combines those options; first one choses the client type (e.g., public, confidential), and then the grant (e.g., Authorization code flow). Both client types share some of the same grants, with the caviar that the confidential client will require also a client secret to be provided during the execution of the Authentication/Authorization grant.
From the Oauth 2.0 specification:
OAuth defines two client types, based on their ability to
authenticate securely with the authorization server (i.e., ability to
maintain the confidentiality of their client credentials):
confidential
Clients capable of maintaining the confidentiality of their
credentials (e.g., client implemented on a secure server with
restricted access to the client credentials), or capable of secure
client authentication using other means.
public
Clients incapable of maintaining the confidentiality of their
credentials (e.g., clients executing on the device used by the
resource owner, such as an installed native application or a web
browser-based application), and incapable of secure client
authentication via any other means.
As one can read the client type refers to the type of the application architecture. Why do you need those types? The answer is to add an extra layer of security.
Let us look at the example of the Authorization Code Grant. Typically the flow is as follows:
The user goes to an application;
The user gets redirect to the Keycloak login page;
The user authenticates itself;
Keycloak check the username and password, and if correct, sends back to the application an authorization code;
The application receives that code and calls Keycloak in order to exchange the code for tokens.
One of the "security issue" with that flow is that the exchange of code for token happens on the frontend channel which due to the nature of browsers it is susceptible to a hacker intercepting that code and exchange it for the tokens before the real application does it. There are ways of mitigating this but it is out of the scope of this question.
Now, If your application is a single-page application, then it cannot safely store a secret, therefore we have to use a public client type. However, if the application has a backend where the client secret can be safely stored, then we could use a confidential client.
So for the same flow (i.e., Authorization Code Grant), one can make it more secure by using a confidential client. This is because the application will now have to send to Keycloak a client secret as well, and this happens on the backend channel, which it is more secure than the frontend channel.
What is the proper way to delegate access for my legacy application to
some resources (not limited to a specific user ones) of another
application using keycloak ?
The proper grant is to use the so called Client Credential Grant:
4.4. Client Credentials Grant
The client can request an access token using only its client
credentials (or other supported means of authentication) when the
client is requesting access to the protected resources under its
control, or those of another resource owner that have been previously
arranged with the authorization server (the method of which is beyond
the scope of this specification).
Since this grant uses the client credentials (e.g., client secret) you can only use it if you have selected confidential as the client type.

Why does OAuth 2 have Resource Owner Password Credentials Grant?

Why would anyone use OAuth 2 with this kind of grant? I mean, if the client already has the name and password of the Resource Owner, why not just authenticate as the Resource Owner using whatever authentication vehicle is used by the Resource Server?
I do not understand the rationale here. Can someone explain it?
As the spec mentions, the Resource Owner Password Credentials grant is for migration purposes and applicable only in scenario's where (typically) the Client and the Authorization Server are controlled by the same party, https://www.rfc-editor.org/rfc/rfc6749#section-1.3.3:
The resource owner password credentials (i.e., username and password)
can be used directly as an authorization grant to obtain an access
token. The credentials should only be used when there is a high
degree of trust between the resource owner and the client (e.g., the
client is part of the device operating system or a highly privileged
application), and when other authorization grant types are not
available (such as an authorization code).
It allows for utilizing a standard token and protocol on the leg between Client and Resource server (e.g. OAuth 2.0 Bearer Token), whilst using a "to-be-deprecated" way of getting a token between Client and Authorization Server. https://www.rfc-editor.org/rfc/rfc6749#section-10.7:
The resource owner password credentials grant type is often used for
legacy or migration reasons. It reduces the overall risk of storing
usernames and passwords by the client but does not eliminate the need
to expose highly privileged credentials to the client.
This grant type carries a higher risk than other grant types
because it maintains the password anti-pattern this protocol seeks
to avoid. The client could abuse the password, or the password
could unintentionally be disclosed to an attacker (e.g., via log
files or other records kept by the client).
Additionally, because the resource owner does not have control over
the authorization process (the resource owner's involvement ends when
it hands over its credentials to the client), the client can obtain
access tokens with a broader scope than desired by the resource
owner. The authorization server should consider the scope and
lifetime of access tokens issued via this grant type.
The authorization server and client SHOULD minimize use of this
grant type and utilize other grant types whenever possible.
I will provide another point of view.
OAuth 2.0 is a great protocol for common web applications. Some applications, however, use much stronger authentication / authorization mechanism. For these cases, it makes sense to allow token establishment using a strong method. An example of such application can be a banking API - it can use classic OAuth 2.0 flow on web (using bank's website) and strong data signatures using protocols like PowerAuth 2.0 (I am an author of this solution) for native mobile or desktop apps.

Are Client Credentials optional in the oAuth2 Resource Owner Password Credentials Grant flow?

4.3.2 of RFC 6749 (which describes the "Resource Owner Password Credentials Grant flow" of the oauth2 Authorization Framework) states:
If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.
Can't seem to find a reference as to what a "confidential client" is. From this it seems that it's allowed to have non-confidential clients participate in the "Resource Owner Password Credentials Grant flow" (4.3). I.e. clients that won't (and can't) authenticate themselves with the Authorization Server.
Is this correct?
Check out the client types section, where the definition of "confidential clients" is given as:
Clients capable of maintaining the confidentiality of their
credentials (e.g., client implemented on a secure server with
restricted access to the client credentials), or capable of secure
client authentication using other means.
Cloudfoundry's command-line cf application is an example of a "public" (i.e. non-confidential) client which uses the password grant.
Section 2.3 of the oauth2 specification has the following paragraph:
The authorization server MAY establish a client authentication method with public clients. However, the authorization server MUST NOT rely on public client authentication for the purpose of identifying the client.
Where a public client is defined in section 2.1 as:
Clients incapable of maintaining the confidentiality of their credentials (e.g., clients executing on the device used by the resource owner, such as an installed native application or a web browser-based application), and incapable of secure client authentication via any other means.
So, you can (optionally) authenticate the client but not take that the mean that the client is who it says it is.

Resources