asap/lib.rs
1//! This is a rust library for generating and validating ASAP tokens. It provides
2//! options for doing so that are compliant with the [ASAP specification](https://s2sauth.bitbucket.io/spec/).
3//!
4//! ASAP is a protocol that extends JWT. It does this so resource servers can be
5//! confident that incoming requests with signed ASAP tokens are indeed coming
6//! from the intended client. If you want to know more, see [the specification](https://s2sauth.bitbucket.io/spec/).
7//!
8//! Things to note about this ASAP library:
9//!
10//! * This library is *awesome*. If you use Rust and want ASAP, you should use this!
11//! * At the moment it only supports the `RS256` algorithm. This is the most used
12//! algorithm that ASAP uses, so there's been no need to implement any others.
13//! * The ASAP `Validator` struct can optionally detect duplicate `jti` nonces.
14//!
15//! This library aims to be fully compliant with the ASAP specification [found here](https://s2sauth.bitbucket.io/spec/).
16//! If you notice anything out of the ordinary, please don't hesitate to make a Issue
17//! or PR stating where it doesn't comply.
18//!
19//! This library also aims to be really simple to use! You should concentrate
20//! less on ASAP, and more on writing your client or service. If you spend too
21//! much time working with this library, then it's failed its purpose. Please
22//! make an Issue/PR telling us why, and we'll do our best to make it better.
23//!
24//! Here's a quick example of how you can generate tokens using this library:
25//!
26//! ```rust
27//! # extern crate asap;
28//! # extern crate serde;
29//! # #[macro_use] extern crate serde_json;
30//! #
31//! use asap::claims::Aud;
32//! use asap::generator::Generator;
33//!
34//! // The identifier of the service that issues the token (`iss`).
35//! let iss = "service01".to_string();
36//! // The key id (`kid`) of the public key in your keyserver.
37//! let kid = "service01/my-key-id".to_string();
38//! // The `private_key` used to sign each token.
39//! let private_key = include_bytes!("../support/keys/service01/1530402390-private.der").to_vec();
40//!
41//! // Here's your generator! 🎉
42//! let generator = Generator::new(iss, kid, private_key);
43//!
44//! // Generate tokens, etc...
45//! # let aud = Aud::One("aud".to_string());
46//! # let extra_claims = None;
47//! let token = generator.token(aud, extra_claims).unwrap();
48//! ```
49//!
50//! And here's another example of how you can validate tokens:
51//!
52//! ```rust
53//! # extern crate asap;
54//! # extern crate serde;
55//! # #[macro_use] extern crate serde_json;
56//! #
57//! # use serde::de::DeserializeOwned;
58//! use asap::claims::Claims;
59//! use asap::validator::Validator;
60//!
61//! # #[tokio::main]
62//! # async fn main() {
63//!
64//! let asap_token = "<your-asap-token>";
65//!
66//! // The keyserver(s) which hosts your public keys.
67//! let primary_keyserver = "http://my-keyserver/".to_string();
68//! let fallback_keyserver = "http://my-fallback-keyserver/".to_string();
69//! // The audience of the server/resource that validates the incoming tokens.
70//! let resource_server_audience = "my-server".to_string();
71//!
72//! // Build the ASAP validator:
73//! let validator = Validator::builder(primary_keyserver, resource_server_audience)
74//! .fallback_keyserver(fallback_keyserver)
75//! .build();
76//!
77//! // A list of issuers that are allowed to access this server/resource.
78//! let whitelisted_issuers = vec!["list", "of", "whitelisted", "issuers"];
79//! match validator.decode(asap_token, &whitelisted_issuers).await {
80//! Ok(token_data) => {
81//! // Here you have a successfully verified and accepted access token!
82//! //
83//! // Remember the directions from the ASAP spec:
84//! // If the resource server successfully verifies and accepts the
85//! // access token, then it MUST process the request and it MUST assume
86//! // that the request was issued by the issuer.
87//! println!("claims {:?}", token_data.claims);
88//! },
89//! Err(e) => {
90//! // Oh boo, there was an error decoding and validating the ASAP token.
91//! //
92//! // Remember the directions from the ASAP spec:
93//! // If the resource server rejects the access token, then it MUST
94//! // reply with a status code of 401 UNAUTHORIZED and MUST include a
95//! // WWW-Authenticate header field as per the HTTP specification.
96//! eprintln!("{:?}", e);
97//! }
98//! }
99//! # }
100//! ```
101//!
102//! That's really it! It should be simple - that's the goal.
103
104extern crate chrono;
105#[macro_use]
106extern crate anyhow;
107#[cfg(not(feature = "fips"))]
108extern crate jsonwebtoken as jwt;
109#[cfg(feature = "fips")]
110extern crate jsonwebtoken_aws_lc as jwt;
111extern crate lru_time_cache;
112extern crate pem;
113extern crate rand;
114extern crate reqwest;
115extern crate serde;
116extern crate thiserror;
117#[macro_use]
118extern crate serde_derive;
119#[macro_use]
120extern crate serde_json;
121
122pub mod claims;
123mod errors;
124pub mod generator;
125mod util;
126pub mod validator;