Importancy of validate Issuer and audience in JWT, When app is the only token provider for itself - oauth

Sounds like stupid question, But i cannot find/infer answer of following question from many articles.
Who is Issuer? (probably the token provider we trust. Like "Google, Faceboock, etc" and our site accepts tokens from theme).
Who is Audience?
Should i validate these two if i don't use OAuth and OpenID? I mean, Are they only used for 3rd-party authentication/authorization (because my site is the only issuer of my own tokens)?
What risk should i take if i don't validate these two, when my site don't use 3rd-parties to authenticate and authorize?

yes, the issuer is the Provider of the token
the Client i.e. the recipient in OpenID Connect, the Resource Server in OAuth 2.0
if a JWT has an audience, the recipient should validate that it is the audience
someone uses a token that was issued for a different service/API (e.g. API B) against your service/API (e.g. API A)

Related

Access tokens and id tokens

I am pretty new with these protocols, and I am having some trouble understanding something.
I am currently working on an application which API and Frontend is mine, I use azure identity platform to receive the tokens on the clientside and send the token to the server that validates the token using passport-azure-ad bearerStrategy. (I have my app registration for that purposes ofcourse).
The thing that I don't get, is that I missed correctly used the tokens I received from azure in my client and sent the ID Token to my API, it verifes it as a valid one and user is authenticated to perform the request sent.
But, as I read here https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens, and in any other article about oAuth2 and openID, ID tokens are for UX stuff and client, while I should have used the access token in my request to my API.
But howcome the ID Token is also verified in my API? It makes no sense for me, or am I missing something?
And if so, is there any vurlnabilty in using Id Token as I did?
Thank you!
APIs should first validate the JWT access token, to check these fields have allowed values. An ID token will then fail the audience check.
JWT signature
Not expired / valid at this time
Issuer (a Microsoft ID)
Audience (eg api.mycompany.com)
Access tokens have scopes, whereas ID tokens do not. Every API endpoint should validate the received scope, eg to ensure that it has received the right type of token. This will also ensure that the API does not accept ID tokens.
So although some API tech stacks accept ID tokens, making the standard checks will ensure the right behavior. And the real API authorization is then done using claims, to apply your business rules.

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.

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.

Client ID or Multiple Audiences In JSON Web Token

I am implementing OAuth 2.0 with JWT in my application and am having trouble deciding what to set as my aud claim as. A user will "login" to my client via my authentication server to gain access to my API (resource) server. I want my tokens to only be valid for use with a specific client and specific API.
When logging in from my client, I include it't client_id in the request, but in most implementations I've found, the aud is set to that client_id. I'm leaning towards including a customer audience_id field in my login request and then setting the aud in the token to an array of the client_id and the audience_id, but that feels like it just means that that token is valid for both those audiences, which makes me think I should just add a custom claim called client to specifically state that this token was created for a specific client.
I have not come across any implementations online that include both a client_id and audience_id(s) in an OAuth login request, nor do I see a reserved claim for client in the spec.
Am I missing something here?
What is best practice for specifically stating a different client_id and audience_id in a JWT?
The audience of the JWT is the Resource Server as that is where the token will be processed, i.e. verified, inspected and acted upon. From RFC 7519, https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3:
The "aud" (audience) claim identifies the recipients that the JWT is
intended for. Each principal intended to process the JWT MUST
identify itself with a value in the audience claim.
[...]
The interpretation of audience values is generally application specific.
[...]
So best practice is that aud should identify the Resource Server.
The Client is only the presenter of the token and it is best practice (i.e. in OpenID Connect and some emerging OAuth 2.0 exension drafts) to use the azp (Authorized Presenter) for that claim. From http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken :
azp
OPTIONAL. Authorized party - the party to which the ID Token was
issued. If present, it MUST contain the OAuth 2.0 Client ID of this
party. This Claim is only needed when the ID Token has a single
audience value and that audience is different than the authorized
party.
[...]
So best practice is that azp identifies the Client.

Weakness in oAuth 2.0 - what are the alternatives?

I am working on a mobile application that uses an api built with ASP.NET web api framework. We decided to use ACS alongside a custm STS as a mechanism to secure the api.
We are using a custom STS because we need to authenticate users against our own identity store.
The information flow is as follows:
Mobile app calls the custom STS with user credentials.
User is authenticated against our own identity store.
Once user is authenticated an authorization code is retrieved from ACS and used to retrieve an SWT access token.
Token is returned to mobile app.
Mobile app embeds access token in authorization header and fires request to API
HTTP module in API validates the access token and data is returned if the token is valid.
Everything is done over SSL as we are using oAuth 2.0.
The problem with oAUth 2.0 is that it is at risk from man-in-the-middle attack as the SWT token issued by ACS is a raw token and not encrypted in any way. It is however, signed using a 256bit symmetric key.
We are using swt tokens because we are using an http based approach and the token fits nicely into the auth header of an http request.
Microsoft have provided some ACS security guidelines in the following post:
http://msdn.microsoft.com/en-us/library/windowsazure/gg185962.aspx
we currently implement 2 of these as we check the issuer and the audience i.e that the token was issued by our trusted issuer (ACS) and that the token was issued for the correct audience (our api).
our scenario is based on the following article:
http://msdn.microsoft.com/en-us/library/hh446531.aspx
as such WIF is not used to handle incoming tokens. WIF is only used in claims processing.
given the above mentioned scenario is there anything else that we could be doing to improve the implementation we have to secure our rest based api?
any and all comments/criticism/suggestions welcome.
Thank you.
I think you're already taking the correct approach. The most important thing is to verify if the token is signed by ACS. Never share your ACS secret key with anyone else. If they don't know the key, they cannot forge the signature.
Also do not store confidential information in the token (such as password, credit card number, etc.). You should expect the token may be obtained by someone else, but no one can forge a token with the correct signature.

Resources