I have Azure AD B2C, and am I using it to secure an Azure Function. Users authenticate with the Azure Function by providing a JWT Bearer Token for authorization in the header.
This all works correctly.
I have now tried to apply the Allow Token Audience in the Authentication / Authorization configuration panel.
I had thought Allow Token Audience would validate the audience (aud) claim of my JWT token - which for my JWT token matches my Client Id.
This does not appear to be the case. All the values I supplied for Allow Token Audience are incorrect, but users are still successfully authenticated.
How is Allow Token Audience supposed to be used?
Per the comments, the issue seems to be that the client ID is accepted as an audience. This is expected behavior. App Service always allows the client ID and the base site URL (yoursite.azurewebsites.net) as valid audiences. The "Allowed token audiences" option is meant to provide additional audiences, such as if you were using a custom domain, etc.
This is certainly confusing. There are probably UX improvements that could communicate this better (info balloon, list entries that can't be removed, etc.).
Related
We have a number of services that can be called by users via HTTP based protocols (SOAP/REST/WebDAV). The services support various authentication mechanisms (e.g. Basic, and OIDC Bearer tokens). Sometimes a service has to call another service without a live user. For that, we configure technical users, and service A can call B with the credentials of a technical user.
For OAuth/OIDC authentication via Bearer tokens, we use the JWT bearer token flow to acquire access tokens for our technical users: Service A creates a JWT with the name of the technical user and signs it with its own private key. It then calls the OIDC token endpoint with that token and receives an access token for its technical user X. It can then use this token as a bearer token to call service B, which will accept the token for user X. (For more information on the JWT bearer flow, cf. RFC 7523 section 2.1 and RFC 7521 section 4).
This works fine with our Connect2id test server and also with Salesforce, but we haven't been able to get it working with Azure. Accessing Azure's token endpoint always results in the following error response:
AADSTS50027: JWT token is invalid or malformed
According the Microsoft's documentation, this error can have any number of reasons:
doesn't contain nonce claim, sub claim
subject identifier mismatch
duplicate claim in idToken claims
unexpected issuer
unexpected audience
not within its valid time range
token format is not proper
External ID token from issuer failed signature verification.
When trying to find out more about Azure and the JWT bearer flow, the only solid information I've been able to locate is this article:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
It describes the "On-Behalf-Of" (OBO) flow, which as far as I understand is an extension (by Microsoft?) to the JWT bearer flow, adding a second JWT to the mix along with a parameter called "requested_token_use" set to "on_behalf_of". I can only find "requested_token_use" in relation to the special OBO flow, and its only value seems to be "on_behalf_of".
OBO flow isn't what we want, since it seems to allow a service X to turn a token received by service Y into another token, using the Y token and a self-generated X token to call the token endpoint. Our use case only has a self-generated X token and the name of the user who the app is permitted to impersonate.
After a lengthy trial & error phase we've come to the impression that OBO may in fact be the only (non-standard) version of the JWT bearer flow that Azure knows about, and that it may not support the "normal" JWT bearer flow we're trying to use at all. Is this correct, and we have no option but to give up trying to solve this scenario with standard OIDC when Azure is involved, or does Azure in fact also support the flow we've implemented and we're just doing something wrong (e.g. wrong audience or issuer in our JWT, or a mis-configured app in Azure)?
PS: Our code is written in Java and we use the Nimbus library for our OAuth/OIDC communication.
I'm struggling to understand when to use a session cookie, or just use the IdP issued token as a bearer token.
Is the primary advantage of using an IdP issued token that you get a standards based mechanism for tokens (including ensuring non-tampering, as the JWT is signed)?
As opposed to using a proprietary vendor mechanism of converting it to a claim identity, and then to a custom session cookie (as per owin middleware)?
Doesn't the custom cookie approach have an advantage that one can add non-ipd issued claims (eg: from a system db)?
What other key advantage does using an idp issued id_token have over a cookie based session approach?
Is it maybe that a bearer token approach would not need caching on the server, so that one can re-use it to call 3rd party services that have a different audience value? Whereas the token would be lost if we used a cookie? (I'm reaching, I know, as I don't yet understand how calling 3rd party services works).
The Id token is meant for your user-facing app as proof of who the user is.
It is then up to your app how you choose to authenticate the user on future requests.
While technically you could just store the Id token and use that, as you mentioned, it cannot be extended since it is digitally signed.
Which for most our projects is no good.
At least in regular Azure AD (not sure about B2C), you cannot use the Id token to get an access token for another API.
In there, you would have to get an authorization code in addition to the Id token at the time of sign in,
and exchange that for an access token (which you then cache server-side).
If you use the Id token as an authentication token for your app, keep in mind that Id tokens issued from the token endpoint (when exchanging an authorization code in normal Azure AD) are not signed (I guess since you receive them as a response to your request + over HTTPS).
Only the Id token you get in the redirect back to your app is signed in normal AAD.
I am not sure if this applies to B2C as well.
I'm trying to implement OpenID Connect Implicit Flow. The frontend Single Page App passes the ID Token down to the backend server (using Authorization header) where I need to validate it.
The documentation requires me to check that I trust the audience of the token (aud & azp fields). I'm struggling to understand the significance of this validation step and what are the security implications of not doing so. Why should I distrust the token if I'm not the intended recipient?
My reasoning is that if I trust the issuer it doesn't matter who was the token issued for. I would expect the claims to be the same for any clientId (is this wrong?). Ideally when I pass the ID Token around my microservices all they should know is what issuers to trust (and use discovery protocol for figuring out the keys).
What is the attack vector if I skip this validation step?
The issuer could be issuing tokens to different applications and those applications could have different permissions. Not checking the audience would allow an attacker to use a token issued for application A at application B and may lead to permission elevation.
To your suggestion: the claims may indeed differ per Client.
Here's another reason: If you check that aud claim only contains your client, it prevents other apps' stolen tokens from being used on your app. If a user's token gets stolen from another app, nobody will be able to impersonate the user on your app because the aud claim will not be correct.
I'm answering this for posterity.
You should check the issuer and if your client_id is the only one in the audience if you are receiving tokens from an external OpenId Provider. One that could have more than your client.
Claims are not global to the OpenID Provider, they can be per-client. A user can have "Admin" role on app-A, gets a token there, then tries to send app-B (your application) the same token hoping that your are not checking to which client it was issued for (its audience).
I have created AuthorizationServer using OWIN/Katana OAuth 2.0 Authorization Server. It is configured to use JWT as the AccessTokenFormat. The SigningCredentials here are derived from Audience Secret that is unique to each Audience.
I want to build a Client that uses this AuthorizationServer to get a token for using an couple of API's I've built (resource / audience).
I see in OAuth there is no concept of Audience (JWT concept), the only thing closest to this is a Scope. I can pass multiple scopes (audience) from Client but I don't understand how can I create a JWT in this case since multiple Audience are required to be able to validate the resulting token.
Any help or guidance appreciated.
You should be careful not to confuse two different concepts. The Audience claim indicates for who the access token is intended. You can only use it for services that have that value configured in the allowed audiences.
Scopes limit what the client can do with the token on the service. For example, one scope may allow the client to post to your feed, while another scope gives it access to your list of followers.
So you would typically need two different tokens to access two different APIs. That does not mean the user needs to authenticate twice though.
The authentication happens on the authorization server and while the user is still logged in to that server, he/she won't be prompted for credentials again. The user will be prompted for consent the first time they try to access a new API.
I'm currently studying OAuth 2.0 and OpenID Connect and I have a doubt regarding the Authorization Server and Access Tokens. The spec defines the Authorization Server as:
The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.
So as I understood, the client redirects the user to the Authorization Server, the user authenticates itself at the Authorization Server and the Authorization Server issues an access token to the client.
Now here comes a thing I couldn't understand until now. There are two possible ways to understand this and I'm trying to get the right one:
The Authorization Server issues the access token containing the user's claims. The access token with the user's claims is sent with each request to the resource server and the resource server is able to read those claims and based on then allow or deny access to resources.
The Authorization Server issues the access token already containing explicit instructions to allow or deny access to resources on the resource server. The resource server thus just reads this information to see if the user can do something or not.
The first option seems to be right way to understand the thing. In that case the Authorization Server will manage the user's claims and issues tokens containing just the claims (things like birthday, age, role and so on). This, in turns gives another responsibility to the resource server: deciding based on claims if a resource is available or not.
The second option is much more limited. Instead of just issuing claims the authorization server would need to issue authorization for each resource, and the token could get quite heavy and mananging this complexity seems to be hard.
So is my understanding correct? The Authorization is thus responsible for managing user claims and issuing token containing just the claims? On the other hand the resource server is responsible for allowing or not the access to resources based on claims?
An access token does NOT contain a user's claims, but an ID token does.
An authorization server is responsible for managing access tokens, but it does not necessarily have to manage users' claims. There should be a separate server that manages users' claims.
No. 2 sounds weird, because existence of an access token means "authorization has been granted."
OAuth 2.0 (RFC 6749) is a specification for authorization. OpenID Connect is a specification for authentication. Don't be confused.