Skip to content

cfsamson/azure-jwt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

84 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A library that authenticates Azure JWT tokens

Crates.io Chrono on docs.rs

Note

As of version 0.4.3 this crate has one dependabot alert. This is fixed in the main branch by updating the jsonwebtoken crate to >10.0.3. However this change neccecitated several changes to the test files in how we build the RSA test keys. I'm still reviewing these changes to try to verify them before releasing a new update. Any contributions in this regard by reviewing or expanding the test suite is greatly appreciated. Unless you're impacted by the dependabot alert directly, this crate should be perfectly fine to use with the latest official release.

This library will fetch public keys from Microsoft and use those keys to validate the authenticity of a token you provide. It defaults to validating and mapping Azure Id tokens for you out of the box.

We fetch Azures public keys by sending request for them through the open-connect api. The default is to expire the stored keys after 24 hours and fetch new ones since that correspond with the normal key rotation scheme. There is also a default retry fallback where a kid that doesn't match any of our current public keys wil trigger one refresh of the keys (limited to once an hour), just in case the set default is badly synced with the rotation of the public keys or Microsoft decides to rotate the keys immediately for some reason. Both of these settings can be configured.

Async and blocking versions

This library now supports both an async and a blocking API. By default both API's are included which means that you get two different versions like this:

// blocking version
AzureAuth::new()

// async version
AzureAuth::new_async()

If you only need the async api and don't want to compile the blocking version,you can simply specify that in Cargo.toml like this:

[dependencies]
azure_jwt = { version = "*", default-features = false, features = ["async"] }

The same applies if you only want the blocking API.

azure_jwt = { version = "*", default-features = false, features = ["blocking"] }

Example

use azure_auth_rs::*;

let client_id = "my client id from Azure";
let mut az_auth = AzureAuth::new(client_id).unwrap();

let decoded = az_auth.validate_token(TEST_TOKEN)?;

Performance

When you create a new AzureAuth instance in its default configuration it will trigger two calls to Microsoft endpoints (one to get the open connect metadata to get the current jwks_uri and one to fetch the jwk sets). You should create these objects with care and prefer using a reference to one instance. If you're using it on a webserver you should avoid creating a new instance on every connection and rather instantiate one on server start and use a mutex or channels to do validation. Once the keys are loaded the operations should be very fast. More benchmarks are however needed to confirm this, but the current benchmark indicates around 34 us to perform a validation on my 2020 Ryzen 3900X processor, once the public keys are retrieved (which should only occur every 24h if set up correctly).

Security

This library validates six things:

  1. That the token is issued by Azure and is not tampered with
  2. That this token is issued for use in your application
  3. That the token is not expired
  4. That the token is not used before it's valid
  5. That the token is not issued in the future
  6. That the algorithm the token header specifies the right algorithm*

The validation will Error on a failed validation providing more granularity for library users to find out why the token was rejected.

You'll need:

You will need a private client_id created by Azure for your application to be able to verify that the token is created for your application (and not anyone with a valid Azure token can log in). This is the ID this library needs from you to authenticate that the token vas issued for your application.

You get a verified token parsed for you in return.

You still must take care of:

  1. Validating that the user has the right access to your system
  2. Validating any other information that is important for your use case
  3. If you ask for more information about the user than what is defined in Microsoft ID tokens reference you will need to make a Struct that maps to all the fields in the token and use the custom_validation method.

For more information, see this article: https://docs.microsoft.com/en-us/azure/active-directory/develop/id-tokens

About

A library for validating OAuth tokens from Azure AD

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages