pub struct Header {
pub protected: HeaderMap,
pub unprotected: HeaderMap,
}
Expand description
Header for a Common Access Token.
The header contains metadata about the token, such as the algorithm used for signing and the key identifier. It is divided into two parts:
-
Protected Header: Contains parameters that are integrity-protected and included in the signature input. This typically includes the algorithm.
-
Unprotected Header: Contains parameters that are not integrity-protected and can be modified without invalidating the signature. This might include non-critical metadata.
§Examples
Creating a header with algorithm and key identifier:
use common_access_token::{Algorithm, Header, KeyId};
let header = Header::new()
.with_algorithm(Algorithm::HmacSha256)
.with_protected_key_id(KeyId::string("my-key-2023"));
assert_eq!(header.algorithm(), Some(Algorithm::HmacSha256));
Fields§
§protected: HeaderMap
Protected header parameters (must be integrity protected)
unprotected: HeaderMap
Unprotected header parameters
Implementations§
Source§impl Header
impl Header
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new empty header with no parameters.
§Example
use common_access_token::Header;
let header = Header::new();
assert!(header.protected.is_empty());
assert!(header.unprotected.is_empty());
Sourcepub fn with_algorithm(self, alg: Algorithm) -> Self
pub fn with_algorithm(self, alg: Algorithm) -> Self
Sets the algorithm in the protected header.
The algorithm is always placed in the protected header because it is a critical parameter that must be integrity-protected.
§Example
use common_access_token::{Algorithm, Header};
let header = Header::new().with_algorithm(Algorithm::HmacSha256);
assert_eq!(header.algorithm(), Some(Algorithm::HmacSha256));
Sourcepub fn with_protected_key_id(self, kid: KeyId) -> Self
pub fn with_protected_key_id(self, kid: KeyId) -> Self
Sets the key identifier in the protected header.
The key identifier in the protected header is integrity-protected and cannot be modified without invalidating the signature.
§Example
use common_access_token::{Header, KeyId};
let header = Header::new().with_protected_key_id(KeyId::string("my-key-2023"));
if let Some(KeyId::String(kid)) = header.key_id() {
assert_eq!(kid, "my-key-2023");
}
Sourcepub fn with_unprotected_key_id(self, kid: KeyId) -> Self
pub fn with_unprotected_key_id(self, kid: KeyId) -> Self
Sets the key identifier in the unprotected header.
The key identifier in the unprotected header is not integrity-protected and can be modified without invalidating the signature.
§Example
use common_access_token::{Header, KeyId};
let header = Header::new().with_unprotected_key_id(KeyId::string("my-key-2023"));
if let Some(KeyId::String(kid)) = header.key_id() {
assert_eq!(kid, "my-key-2023");
}
Sourcepub fn algorithm(&self) -> Option<Algorithm>
pub fn algorithm(&self) -> Option<Algorithm>
Gets the algorithm from the protected header.
Returns None
if the algorithm is not present or is not a valid algorithm.
§Example
use common_access_token::{Algorithm, Header};
let header = Header::new().with_algorithm(Algorithm::HmacSha256);
assert_eq!(header.algorithm(), Some(Algorithm::HmacSha256));
let empty_header = Header::new();
assert_eq!(empty_header.algorithm(), None);
Sourcepub fn key_id(&self) -> Option<KeyId>
pub fn key_id(&self) -> Option<KeyId>
Gets the key identifier from the protected or unprotected header.
This method first checks the protected header, and if the key identifier is not found there, it checks the unprotected header.
Returns None
if the key identifier is not present in either header.
§Example
use common_access_token::{Header, KeyId};
let header = Header::new().with_protected_key_id(KeyId::string("my-key-2023"));
if let Some(KeyId::String(kid)) = header.key_id() {
assert_eq!(kid, "my-key-2023");
}
let empty_header = Header::new();
assert_eq!(empty_header.key_id(), None);
Examples found in repository?
124fn verify_token(token_bytes: &[u8], key: &[u8], expected_token_type: &str) {
125 // Decode the token
126 let token = match common_access_token::Token::from_bytes(token_bytes) {
127 Ok(token) => token,
128 Err(err) => {
129 println!("Failed to decode {} token: {}", expected_token_type, err);
130 return;
131 }
132 };
133
134 // Verify the signature
135 if let Err(err) = token.verify(key) {
136 println!(
137 "Failed to verify {} token signature: {}",
138 expected_token_type, err
139 );
140 return;
141 }
142
143 // Verify the claims
144 let options = VerificationOptions::new()
145 .verify_exp(true)
146 .verify_nbf(true)
147 .expected_issuer("example-issuer")
148 .expected_audience("example-audience");
149
150 if let Err(err) = token.verify_claims(&options) {
151 println!(
152 "Failed to verify {} token claims: {}",
153 expected_token_type, err
154 );
155 return;
156 }
157
158 // Get the key ID
159 let kid = token.header.key_id().expect("No key ID in token");
160 let kid_str = match &kid {
161 KeyId::Binary(data) => format!("Binary key ID: {:?}", data),
162 KeyId::String(data) => format!("String key ID: {}", data),
163 };
164
165 println!(
166 "Successfully verified {} token ({})",
167 expected_token_type, kid_str
168 );
169
170 // Print some claims
171 if let Some(iss) = &token.claims.registered.iss {
172 println!(" Issuer: {}", iss);
173 }
174 if let Some(sub) = &token.claims.registered.sub {
175 println!(" Subject: {}", sub);
176 }
177 if let Some(exp) = token.claims.registered.exp {
178 println!(
179 " Expires at: {} (in {} seconds)",
180 exp,
181 exp - current_timestamp()
182 );
183 }
184}