Understanding OpenId Connect client_credentials grant in terms of identity - oauth-2.0

I have trouble understanding the client_credentials grant in terms of identity. I have secured my web app with OpenId Connect using the authorization code flow. This works as expected and a proper access and id token are returned from the authorization server. So far so good.
Now i have some public APIs i want to give my customers access to. The access to this APIs is done via our different client libraries that we provide.
In many examples out there the client_credentials flow is used for that providing a CLIENT_ID and a CLIENT_SECRET to get an access token. According to the spec this flow involves no end user and therfore no identity token is returned.
Now i am in trouble because i don't know the identity of the caller. The only thing i can say is that the access token is valid but how is this done in practice ?
How do you know which user called your service when using this flow ? Do i have to save a mapping from user_account to client_id/client secret and query for that in my api endpoint to get the user ? I have to make some access decissions based on the identity who called the service.
If that would be true what benefit does OpendId Connect provide for me in that manner when i can get no id token in that flow ? Doing this with simple Oauth2 client_credentials flow will lead to the same result.
Can someone give me some tipps ?

The client_credentials flow is not meant to be used in scenario's where you want to identify an end user. In fact the client_credentials grant type is undefined in OpenID Connect. You should rely on the Authorization Code grant as you suggest.

Related

OAuth and OpenID connect uses

I've began to take interest in the OAuth 2.0 specification and am not sure if what I've understood so far is correct.
OAuth is an authorization protocol while OpenID Connect is an authentication protocol which extends OAuth.
The first deals with authorizing access to a 3rd party resource, by a client application. Example you are building some app and would like to use some other application (which is not yours to own) features (resources).
On the other hand OpenID connect, deals with authorization, authorizing some human entity by verifying his/hers identity to, for example, access a specific resource that only him/her alone has access to. Example you're a banking application and allow users to access their account but first they need to confirm their identity with an Authorization Provider.
So is it safe to say that Authorization is destined to application interaction while Authentication for human interaction ?
Your understanding on OAuth and OpenID Connect is correct. When OAuth was introduced, it define a way to obtain access tokens, which the holding party can used against an endpoint protected by OAuth access tokens. This allowed identity details to be stored in a central location (authorization server aka identity servcer) and that central location to maintain token obtaining process (which include human authentication too).
While access token are used to grant access (authorize), OpenID Connect introduced ID token that get transmitted along with access token. The ID token is there to be consumed by the client application, which is used to authenticate the end user.
Token obtaining require authentication at authorization server. Depending on the token obtaining flow (aka OAuth grant), this authentication will involve the human user. It is also possible to follow a flow which does not involve a human user. Such flow only produce an access token. And OpenID Connect can only be used when human user is involved.
Q : So is it safe to say that Authorization is destined to application interaction while Authentication for human interaction ?
If your application (client) involves and end user, then that user can involved in token obtaining flow. And you can obtain access token as well as ID Token. Then you use ID token for end user authentication. And access token is used to connect with another endpoint.
If your application does not involved an end user (ex:- A service), then you will use OAuth to obtain access token, which used against another endpoint.

scp claim in Azure AD Acess Token

I'm developing a communication flow through Azure AD with OAuth2. So, I'm testing two flows:
- Credentials Flow
- Authorization Code Flow
Everything works fine, except one thing: The Scope/permission (scp) in the Access Token.
When I request an Access Token with the Authorization Code Flow I have a lot of claims and one very important for my business: the scp. This claim has all scopes configured in the Azure portal.
But when I use the Client Credentials Flow this "scp" claim does not return and I can't check if this Access token generated can access an Endpoint in my resource server.
Any idea how to solve this?
the answer to this question explains quite well why it's not working.
Since there is no redirection (there's not user involved) scp claims are not returned. the solution to your problem is to use application roles.
When you get the OAuth2 token using the client_credentials flow, make sure you are passing the resource parameter and populate it with the appId of the application where you added the roles to the manifest.
Have a look at these two links . Looks like you are correct in the client credential flow scp claims are not visible
Getting the access token for Microsoft Graph API
https://joonasw.net/view/defining-permissions-and-roles-in-aad

OAuth2.0 and OpenID Connect Confusing

I am confused about the use of OAuth 2.0 as an Authorization method and OpenID Connect as an Authentication method.
Based on my knowledge OAuth 2.0 is only an Authorization method. In other words, this is the process to request an ACCESS_TOKEN and RECEIVE this ACCESS_TOKEN, like depicted in the image below in yellow ellipse: (simplified)
Before an OAuth 2.0 Client retrieves an ACCESS_TOKEN from an Authorization Server this Server should verify if the User allows it and this is an Authentication Process that OAuth 2.0 does not care about.
When OpenID Connect is included in the mix it allows for an Authentication Method as well, but in my knowledge OpenID Connect just adds a "Claim" in the JWT Token that holds information about user that is using the service, like: email, name and others.
My questions are:
Why not ignore OpenID Connect and just add more "claims" in OAuth
2.0 to get information about users?
Is my description of the flows correct?
OpenID Connect does not merely "add a claim in JWT Token" but:
it introduces a completely new token (id_token) with radically different
semantics than the OAuth 2.0 access_token and a standardized format that is understood by the Client as opposed to the access_token which is opaque to the Client
it "twists" the role of the Client, now becoming the "audience" (or: intended recipient) of a token (i.e. the id_token) whilst the audience of the access_token is still a remote entity (aka. Resource Server) and the Client is only the "presenter" of the latter
The 2nd item is the primary source of confusion between OAuth 2.0 and OpenID Connect.
I don't know if your method will work or not but you're totally free to roll your own authentication. After all, that's what Facebook, GitHub and many others did by customizing oauth2. There ended up being so many oauth2 "authentication" methods that it was never plug and play if you wanted to change your provider. I believe that's why OpenID connect was introduced--a common way of connecting and reasoning about authentication while building on the established oauth2 pattern for authorization. Use OpenID connect or don't...but if you don't you'll be reinventing the wheel.
#sdoxee answers explains thing correctly. But I am adding bit more information for OP's understanding.
These days many identity providers (eg:- Azure AD) issue JWT based access tokens. These JWT access tokens do contain claims about end user as well as JWT related validation details (eg:- Token expiration). Here is the link for Azure AD OAuth 2 success response which highlights access token to be a JWT. Also, see JWT claims to see how they explain the claims. Samples are given below,
family_name : User’s last name or surname. The application can display this value.
given_name : User’s first name. The application can display this value.
One could think of building authentication on claims present in access token, but this is not sticking with protocol. And mostly claims and user information will be implementer specific. Also, by protocol definition, these two tokens (id and access) have two different audiences.
ID token is for client, for validation and for authentication.
Access token is for OAuth 2 protected endpoint.
Again, as #sdoxee highlight, use the correct protocol at correct place. Having claims in access token does not necessarily mean you should use them for authentication.

Can I authenticate with OAuth Authorization server by passing username and password in Authorization header?

In case of OAuth 2.0 authorization code and implicit flow cases, on hitting the Authorization Url user is redirected to OAuth providers login page.
To avoid showing up the OAuth providers page in my application, can i make user to enter username and password in text fields and pass them as Authorization header of authorization Url and get back access_token from OAuth provider and use it for further requests ?
Is it legal, valid and feasible ?
Is it legal, valid and feasible ?
No. Not with the flow you are using right now. Implicit flow is not built for this purpose, so you cannot do it.
But, OAuth 2.0 provide you a dedicated flow for your requirement.
4.3. Resource Owner Password Credentials Grant
The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged application.
As described in protocol, in this flow, your end user(resource owner) provide their credentials to client application. Client application call token endpoint with resource owner credentials to obtain access tokens.
Flow overview (From RFC6749)
Token request request (From RFC6749)
As specification mention, this flow is there to support old systems which are unable to fully utilise OAuth 2.0. For example clients which use basic authentication.

What OpenID Connect adds to OAuth 2.0 (why is OAuth 2.0 not sufficient for authentication?)

I've read a number of different write-ups on this now, but I'm still unclear as to the primary value that OpenID Connect provides on top of OAuth 2.0.
My understanding:
When receiving an access token via the OAuth 2.0 flow, the client does come to know that the user was authenticated by the authorization server. It seems like OpenID Connect is just adding an ID token with user information - but that information could be part of the access token or available through a protected resource (like a separate userDetails resource). That doesn't seem to justify the creation of OpenID Connect, so I'm sure that I'm missing something...
Thanks for your help!
Adding more details that are too long for a comment. Thanks much for your help so far.
I think I'm getting closer, thanks to your responses. So I reviewed this article: http://oauth.net/articles/authentication/. It says that "OAuth says absolutely nothing about the user". However, you are trusting that same service to authenticate the End-User before issuing an Access Token. In the "common pitfalls section", the article discusses why you can't use access token for authentication. I have the following issues with that in my understanding:
Access token as proof of authentication
The access token was proof of authentication at some prior point. If the Client does want to authenticate the user at some point after getting an access token, why not just repeat the existing Oauth flow with the current end-user trying to access the client?
Access of a protected resource as proof
Same as above - if the client requires authentication at any point, repeat the Oauth flow.
Injection of access tokens
Not clear how OpenID helps this
Lack of audience restriction
Why is it harder to hand a naive client a valid ID token along with the access token? Is this relevant at all to the server-side flow? And again, can repeat the OAuth flow if needed.
Injection of invalid user information
This seems to require a signature, not a separate token. If the OAuth flow takes place over HTTPS, is it adding any security for the identity provider to sign user details twice?
Different protocols for every potential identity provider
This seems fair, but it still seems strange if the only purpose would be standardization of the token used for user information.
An OAuth access token is opaque to the Client and could have been provided by anyone, which means that it is not necessarily handed to the Client by a logged in user. An attacker could provide an access token to the Client that it got from a different user in its own (not necessarily malicious) service. The ID token from OpenID Connect make sure that the user was logged in recently at the OP and provides information about that user that can be verified by the Client. Moreover the ID token is targeted specifically to your Client.
The differences are described pretty well in http://oauth.net/articles/authentication/
An ID token can be signed by the authentication server. A client application can verify the signature to confirm that the end-user has been authenticated by the very authentication server. Access token + protected resource call do not provide such a mechanism.
In addition, OpenID Connect has introduced other mechanisms related to authentication such as:
Authentication Context Class Reference
Maximum Authentication Age
sub claim in claims request parameter
to satisfy higher-level security requirements by governments.
Read OpenID Connect Core 1.0 and other related specifications. Also, you may find "Authorization interaction" helpful as a summary about what OpenID Connect has added to control end-user authentication.
OAuth 2.0 is about granting a third party limited access to a resource. The RFC starts with
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service...
OpenID Connect is about establishing an end-user's identity. The OpenID Connect Core spec starts with
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0
protocol. It enables Clients to verify the identity of the End-User
based on the authentication performed by an Authorization Server...
In OAuth 2.0, when a resource server receives a request containing an access token, the resource server knows that the resource owner has granted a third party access to a resource. The access token represents this approval but it does not identify the third party who is presenting it.
If a company thinks someone like Salesforce or Google is better equiped than they are to manage user accounts, passwords, digital certificates, etc., the company could use OpenID Connect to essentially "outsource" that responsibility to an OpenID Connect Provider. When the company receives an id token in the context of an OpenID Connect flow, it knows that the provider has authenticated the end-user and established the user's identity.
OpenID Connect has repurposed the OAuth 2.0 flows so that the identity of an end-user can be established.

Resources