I know there is lots of material on this point out there but I still dont quite get it.
I know that OAuth2 is not for authentication and that you need OIDC on top to have authentication.
But still don't quite understand why.
If I look a the implicit flow, one of the steps is that the user authenticates to the authorization server and an access token is then issued.
This is authentication, isn't it?
So why do we still need OIDC and the ID token? Is it because the access token itself is not enough and the JWT makes sure the user can be authenticated later on by the backend services?
And how would you do authentication if you only had OAuth2 and no OIDC?
Disclosure: I work for Ping Identity.
I wrote a blog on why OpenID Connect is useful on top of OAuth 2.0, and I think it would help out here.
https://developer.pingidentity.com/en/blog/posts/2019/oidc-adds-authentication.html
Basically, the OAuth 2.0 framework provides a way for the client to ask the authorization server to go and get authorization from the resource owner.
ie, the client says to the authorization server, "I need to access a protected resource owned by John, can you go ask John to authorize this access." The authorization server can then do it's thing and come back with an access token to the client to access the protected resource.
However, if the client asks, "How do I know it was actually John that provided authorization?" the OAuth 2.0 framework doesn't give a way to answer this.
OpenID Connect provides that extra ID token, in addition to the access token, that the client can check to see if it's John.
Related
I'm used to working with ADFS for a long time already and recenlty I was asked to do a proof of concept with Oauth2 on ADFS. Struggling through terminology I managed to set most things up, but still I do have some unanswered questions. Hope someone can shed some light on these...
For SAML / WS-Fed relying parties, it is possible to set custom web content, using Set-AdfsRelyingPartyWebContent. Is this also possible for web api relying parties created in an application group?
Would it be possible to add claims to a client authenticated with client_id / client_secret (server application in ADFS terms) when using the client credentials grant flow?
Even after setting the 'IssueOAuthRefreshTokensTo' 'AllDevices' on the web api application, I still don't receive refresh tokens. What am I missing here?
When posting a token issued by our ADFS on e.g. jwt.io I receive an 'signature validation' error. How can we resolve that?
We would like to set an audience for the access tokens, so applications can use the audience instead of using the appid to verify if they can consume the token. Can we modify the audience?
What does add-adfsclient do? Does it create a client_id, which can then be linked to a relying party (with Grant-AdfsApplicationPermission), thus enabling OAuth2 for an existing relying party?
When configuring a ad user principal for a server application and use 'password' as grant_type with the client credentials grant flow, I cannot seem to find the correct syntax, as ADFS always give the error 'MSIS9622: Client authentication failed. Please verify the credential provided for client authentication is valid.'. I have used the syntax 'user#fqdn' for the username.
Thanks you for helping me out here!
Let me try and work through these.
In ADFS, OIDC applications and WS-Fed / SAML RP are completely different. You can't mix and match.
jwt.io has a signature error because it doesn't know the .well-known endpoint to get the key. Refer this.
To get extra claims you need to add an API as that is the only place for claims rules.
To get a refresh token, you need a scope of "offline_access".
For resource owner password, user name and password are separate fields. Refer here.
Feel free to ask more questions. Just expand your question.
Also, samples here. Look at the menu on the LHS.
Update
What do you mean by "can modify web content on a per relying party basis"?
Re. jwt.io, read this.
For refresh tokens, read this. It seems ADFS doesn't follow the spec here.
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.
I am trying to implement OpenId Connect for SSO in one of my projects. However, I am a bit struggling with the case where I would like to validate OpenId JWT token on Resource Server side to make it stateless. If user tries to logout, authorization Server will know about the user logout (Accordingly OpenId Connect Session Management spec). But how should Authorization Server tell Resource Server that the user's token is not valid anymore? It is a case when user after log out out goes to Resource Server with his OpenId token and gets access. That is weird and I could not find any solution across Internet. Please help me to organize stateless security with central logout.
You can use Token Introspection endpoint to determine whether the access token passed is valid or not. The resource server can make a call to OP's introspection endpoint to validate the token before giving access to the resource. In order to effectively validate the token, the resource server should :
Be a registered client with OP and have Same / similar Scope as SPA app (Implicit flow app) to validate the scopes passed to it and
Have access to Introspection endpoint
The are more details in the above linked Spec for further understanding.
P.S. The answer that I wrote earlier has some other relevant references.
you can use jwt bearer flow, where you can pass ID token/Assertion token to OP in order to generate access token.
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.
OAuth terminology has been bothering me a long time now. Is OAuth Authorization as some would suggest or is it Authentication?
Correct me if I'm wrong but I have always read Authorization as being the act of allowing someone access to a resource yet OAuth doesn't seem to have any implementation that actually allows access to users to a given resource. All OAuth implementations talk about is providing a user a token (signed and sometimes encrypted). This token is then passed with every call to a back-end service endpoint where it is checked for validity, again not an OAuth concern.
Is OAuth Authentication (every article says it isn't) which I take it requires a user to provide credentials which in turn proves a user should/shouldn't have access?
So it seems that OAuth is not Authorization NOR Authentication since these have to be performed by other processes. So what the heck is it? Is it a process for communicating a token? Is it fluff word that really has no specific meaning?
It's hard to ask a question about this subject without sounding enigmatic and superstitious (ghosts and goblins) so I expect that answering this question won't be a simple thing either. Enter at your own risk.
OAuth is a specification for authorization
OAuth 2.0 is a specification for authorization, but NOT for authentication. RFC 6749, 3.1. Authorization Endpoint explicitly says as follows:
The authorization endpoint is used to interact with the resource owner
and obtain an authorization grant. The authorization server MUST first
verify the identity of the resource owner. The way in which the
authorization server authenticates the resource owner (e.g., username
and password login, session cookies) is beyond the scope of this
specification.
OAuth authentication?
Authentication deals information about "who one is". Authorization deals information about "who grants what permissions to whom". Authorization flow contains authentication as its first step. It is the reason people are often confused.
There are many libraries and services that use OAuth 2.0 for authentication. It is often called "social login" and It makes people more confused. If you see "OAuth authentication" (not "OAuth authorization"), it is a solution using OAuth for authentication.
OpenID Connect
OpenID 1.0 and OpenID 2.0 are old specifications for authentication. Those who made the specifications expected people to use OpenID for authentication. However, some people began to use OAuth 2.0 for authentication (not for authorization) and OAuth authentication has prevailed rapidly.
From a viewpoint of OpenID guys, authentication based on OAuth was not secure enough, but they had to admit that people preferred OAuth authentication. As a result, OpenID guys decided to define a new specification, OpenID Connect, on top of OAuth 2.0.
Yes, this has made people much more confused.
One-sentence definitions of OAuth 2.0 and OpenID Connect
OAuth 2.0 is a framework where a user of a service can allow a third-party application to access his/her data hosted in the service without revealing his/her credentials (ID & password) to the application.
OpenID Connect is a framework on top of OAuth 2.0 where a third-party application can obtain a user's identity information which is managed by a service.
(Sorry, these definitions are excerpts from the overview page of my company)
Definitions from a viewpoint of implementors
Authentication is a process to determine the subject (= unique identifier) of an end-user. There are many ways to determine the subject. ID & password, fingerprints, iris recognition, etc.
Authorization is a process to associate the subject with the requested permissions and the client application that requested the permissions. An access token represents the association.
See Also
Full-Scratch Implementor of OAuth and OpenID Connect Talks About Findings
Diagrams And Movies Of All The OAuth 2.0 Flows
Diagrams of All The OpenID Connect Flows
The Simplest Guide To OAuth 2.0
OAuth is an authorization protocol. It is not designed for authentication. Yes, there is a step in the OAuth process where the identity server authenticates a resource owner. The way it happens does not belong to the OAuth protocol. That is why OAuth does not concern itself about authentication.
OAuth performs authorization by giving an access token to a third party (service provider) and that party will be able to authorize access to the resource by presenting the token.
Let's say there is a requirement that a service provider wants to access resources (protected by an identity server) on behalf of the resource owner. So the resource owner will first authenticate and then will grant permission for the service provider to access specific resource. Then the identity server will issue an access token for service provider. Later the service provider can access the resource with that token.
Here, OAuth does not care about who is carrying the access token or trying to access the resources. It validates the access token, and lets the third party access the resources.