Azure AD Signing Keys for JWT - jwt

When you use Open ID connect with Azure AD, the JWT issued token (id token) is signed with an asymmetric key. I saw the public key to verify that signature is available in the metadata file, https://login.microsoftonline.com/common/discovery/keys. However, I couldn't find any documentation about how those keys are generated. How can you change the keys that are available there or how can I specify a different key to sign the JWTs for my tenant ?

All sources and information suggests that this certificate roll over is done by Azure AD them self. Consumers are not able to do a manual roll over or put a certificate of their preference. This claim is supported by this answer. Also, please check this press release which mention a roll over happened in 2016
From your end you must be be ready to accept a rollover any time. Best practice is to fetch key information through discovery document. This is explained in the openid connect documentation

According to this piece of documentation, only way how to have your own signing key for your application, is custom claims mapping. Although description is very vague and instructions how to do it are scarce.

Related

JWT architecture for multiple users?

Most examples always take into consideration only one users using the system in the JWT/Flask tutorials. I want to understand this at a multi-user level but cannot find the correct resources.
Lets say we have the following secret key:
app.config['SECRET_KEY'] = 'randomkey'
Two Questions:
Would this key be the same for every user? if so, wouldn't this provide a security risk because if the key was stolen, anyone would have access to do whatever they want?
If it is not the same, how is the key stored on the server-side so it could be authenticated when requesting information? Would it be stored within the user's table under current token or something?
In this case, that key is the JWT signing key It could also be different from flask's secret key setting (see flask docs). It's not used for encryption so it's not intended to be a shared secret between server and users. Its role is to provide the server with a proof that the JWT content was generated by the server itself: it's a proof of integrity.
Having knowledge of that key means having the right to issue JWTs on behalf of the application, attackers could impersonate servers or make requests with some modified claims, eg pretending to be other users. This means that these keys are quite sensible from security perspective
Turns out that 1 app : 1 key, with some remarks
This key should theorically never change: if at time T1 KEY=x, a user could login in and receive a JWT signed with KEY=x. at T2 KEY=y, the user will invoke some API using the previous JWT and the server will try to verify(signature(payload , x) , y). So every user will be logged out automatically
Despite 1. It would be good to rotate the key. In this case the authentication system should save a buffer of old keys and use them to validate oldest JWT. Since a JWT should be short-lived, it could be useful set a rotation time grater than JWT expire time and just keep the last used key along with the current
This key is a secret and should be managed exactly as other secrets. Aside from terrible approaches like leaving it plaintext in the code/config, there are secret managers from cloud providers, or kubernetes secrets if you use the latter, as well as secret managers from configuration management tools (salt, ansible) or Hashicorp's Vault that is a specialized storage engine for sensible data. Anyway, it's more infra/security team concern if you are in a structured organization

Azure media services: Customize ContentKey authorization policy based on backend data

I've not been able to find decent information in the docs for this. Here's to the internet :)
This is my current understanding:
The documented approach is to create a ContentKeyPolicy with JWT restriction and Media Services will expect the claim added to the token of urn:microsoft:azure:mediaservices:contentkeyidentifier=INJECTED CONTENT KEY ID HERE based on what content the locator URL is serving up.
This means I'd need a new content key for every SKU sold to secure access to the media. Is there a way to hook into this authorization logic to say "I want you to call this API to run my custom validation" where I could check the JWT user's purchased content? This way only one content policy is really needed and becomes manageable.
The custom scenario you described is exactly the reason for using unique content key identifiers.
The way the key delivery server works with JWT tokens is that the key delivery server first checks to see which content key ID is being used. It then checks to see if the token is properly signed with the primary verification key that was used for that locator. Then it validates any claims that were applied when the encryption policies were set.
I'd recommend tracking the primary verification key (if unique per locator), the locator itself, the content key ID, and any claims in your own database so that all of those values are readily accessible for any of your content.

Authorizing asset on a user by user basis

Documentation is quite vague and everything related to this subject mostly points towards AAD.
The requirement I have is to be able to show a video only to users who have a specific permission. This can be as simple as having a claim in their JWT. Using AAD isn't an option so I was wondering if there is any other way I can achieve this.
The way I could imagine this work is that you can specify a claim that you want Azure Media Services to check that the incoming JWT has and then specify the token's AES key or provide a certificate if you choose to go with RS token encryption.
It is NOT required to use any specific token provider (such as Azure AD). You can definitely create your own JWT provider (so-called STS, Secure Token Service), using asymmetric key encryption. In your STS, you can add custom claims as desired based on your business logic.
Make sure the issuer, audience and claims all match up exactly between what is in JWT and the ContentKeyPolicyRestriction used in ContentKeyPolicy in Azure Media Services.

OpenIdConnect: how to add additional claims in the token?

I'm quite new to OpenIdConnect so excuse me if i still miss some basic concept.
I have a SPA-style web application I'm developing for my company (AspNet Core + Aurelia).
I want to use AzureAD via OpenIdConnect for authentication and authorization, everything works very well so far i'm able to obrain a token and sign in.
the problem is that my application needs to provide to the client's browser some app-specific claims like: can read X, can edit Y...
if i add these claims to the JWT token provided by AzureAD obviously it will became invalid, as the signature will not match the content.
if i generate a new token with the new claims, but signed with the app key, obviously it will be a different token valid only in the context of my app (what if I'll later need to access some other resource using the AzureAD token?, is it a good idea to insert the AzureID token as claim of the newly issued token?)
Are there something I'm missing in the OpenConnectId? or is there a way to add claims to a token issued by a 3rd-party provider like AzureAD while keeping the token valid? Maybe a way to ask AzureAd to add claims to the token and re-sign it?
I think a good way to solve this situation may be to obtain an access_token for my own application's api (from my app backend) in exchange of the id_token provided by azure (after its validation)
so the application frontend in the browser will own two tokens and it will be able to use the correct one for each type of request.
there are some standardized flow that are quite similar to this but not exactly the same.
You could try to use a custom claim mapping policy. This is documented here.
This feature is used by tenant admins to customize the claims emitted in tokens for a specific application in their tenant.
As far as I can understand, this is still in preview stage. So it may require some trial and error verification.
Alternatively, you can define some policy in your application itself. Given that you know client IDs from your application (hence you require to use them for OpenID Connect requests), you may create a simple policy to check tokens and perform verifications.

IdentityServer 3 signing certificate expiry

What happens when the signing certificate (used for signing jwt tokens) expires when using IdentityServer 3?
It's unclear to me and I can't find any documentation, other than that it's possible to get a warning that it has expired. (Ref. https://identityserver.github.io/Documentation/docsv2/configuration/events.html)
Is there any mechanism that stops the use of expired signing certs?
And what happens on the client side (client being the Web API that uses IdentityServer for authentication) when validating a token signed by an expired certificate? (For example if https://github.com/IdentityServer/IdentityServer3.AccessTokenValidation is used as a middleware.)
Well I've just tested this (on IdentityServer4) and it seems to continue to work happily with an expired signing certificate, here's my test cert's validity:
I'm able to login, get an ID token and an access token and then access an API with the access token. What IdentityServer does do however is to log a warning:
2017-07-13 12:15:54.871 +02:00 [Warning]
Certificate "CN=test_expired_signing_certificate" has expired on "13/07/2016 14:14:37"
This matches what the IdentityServer (3) docs say here:
IdentityServer raises a number of events at runtime, e.g:
snip...
Expired/invalid/no signing certificate
By default these events are forwarded to the configured log provider - a custom event service can process or forward them in any way suitable for the environment.
So this would be your way of detecting it when it's already too late. A better option is to rollover signing keys periodically and within the validity of the keys, this is the common approach which also allows for a compromised key to be revoked if necessary. See this issue where the process is discussed, basically IdentityServer can handle two keys:
[Middleware refreshes] the metadata document ... once a day.
The metadata doc can hold 2 keys - primary and secondary and the middleware will load and use both when present (JWTs have a key identifier that allows picking the right one).
When you start to rollover - set both keys and at some point swap primary and secondary.
Disclaimer: I never worked with IdentityServer3
The outside world doesn't know your certificate and therefore doesn't know it's expired. The outside world merely sees your public key at:
YourIdentityServer.com/.well-known/openid-configuration
or more accurately:
YourIdentityServer.com/.well-known/openid-configuration/jwks
You can play around with this: Create a new cert on startup (see https://gist.github.com/mykeels/408a26fb9411aff8fb7506f53c77c57a). Even if you set the TimeSpan to one minute, it will keep working.
But once you wait 1 minute and restart your IdentityServer your token from last sign in will be considered invalid, because it was created with the now outdated signing key. It is checked against the new public key and fails.
It seems to be recommended to periodically replace your cert with a new one, while also keeping the previous key around, see "signing key rollover":
https://docs.identityserver.io/en/dev/topics/crypto.html#signing-key-rollover