Skip to content

Commit

Permalink
Added ValidationOptions - direct biscuit ones. See #6 (#14)
Browse files Browse the repository at this point in the history
* Added ValidationOptions - direct biscuit ones. See #6

* Documentation fix using ValidationOptions
  • Loading branch information
olger authored Nov 16, 2022
1 parent 11c3efc commit bf81fc7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ keywords = ["actix", "http", "web", "cryptography"]
license = "MIT"
name = "actix-4-jwt-auth"
repository = "https://github.com/spectare/actix-4-jwt-auth"
version = "0.5.2"
version = "0.6.0"

[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
Expand Down
54 changes: 39 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! use actix_4_jwt_auth::{AuthenticatedUser, OIDCValidator, OIDCValidatorConfig};
//! use actix_web::{get, http::header, test, web, App, Error, HttpResponse, HttpServer};
//! use serde::{Deserialize, Serialize};
//! use biscuit::ValidationOptions;
//!
//! #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
//! pub struct FoundClaims {
Expand All @@ -24,7 +25,8 @@
//! #[actix_rt::main]
//! async fn main() -> std::io::Result<()> {
//! let test_issuer = "https://a.valid.openid-connect.idp/".to_string();
//! let created_validator = OIDCValidator::new_from_issuer(test_issuer.to_string()).await.unwrap();
//! let validation_options = ValidationOptions::default();
//! let created_validator = OIDCValidator::new_from_issuer(test_issuer.to_string(), validation_options).await.unwrap();
//! let validator_config = OIDCValidatorConfig {
//! issuer: test_issuer,
//! validator: created_validator,
Expand Down Expand Up @@ -57,11 +59,11 @@ use biscuit::errors::Error as BiscuitError;
use biscuit::jwa::*;
use biscuit::jwk::JWKSet;
use biscuit::*;
use futures_util::TryFutureExt;
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
use std::format;
use std::sync::Arc;
use futures_util::TryFutureExt;
use thiserror::Error;

mod extractor;
Expand Down Expand Up @@ -155,6 +157,7 @@ pub struct OIDCValidator {
//note that keys may expire based on Cache-Control: max-age=21446, must-revalidate header
/// Contains the JWK Keys that belong to the issuer
jwks: Arc<JWKSet<Empty>>,
validation_options: ValidationOptions,
//client: Arc<awc::Client>,
}

Expand All @@ -163,25 +166,35 @@ impl OIDCValidator {
///
/// The given issuer_url will be extended with ./well-known/openid-configuration in order to
/// fetch the configuration and use the jwks_uri property to retrieve the keys used for validation.actix_rt
pub async fn new_from_issuer(issuer_url: String) -> Result<Self, OIDCValidationError> {
pub async fn new_from_issuer(
issuer_url: String,
validation_options: ValidationOptions,
) -> Result<Self, OIDCValidationError> {
let discovery_document = OIDCValidator::fetch_discovery(&format!(
"{}/.well-known/openid-configuration",
issuer_url.as_str()
))
.await?;
OIDCValidator::new_with_keys(discovery_document.jwks_uri).await
OIDCValidator::new_with_keys(discovery_document.jwks_uri, validation_options).await
}

/// When you need the validator created with a specified key URL
pub async fn new_with_keys(key_url: String) -> Result<Self, OIDCValidationError> {
pub async fn new_with_keys(
key_url: String,
validation_options: ValidationOptions,
) -> Result<Self, OIDCValidationError> {
let jwks = OIDCValidator::fetch_jwks(&key_url).await?;
OIDCValidator::new_for_jwks(jwks).await
OIDCValidator::new_for_jwks(jwks, validation_options).await
}

/// Use your own JSWKSet directly
pub async fn new_for_jwks(jwks: JWKSet<Empty>) -> Result<Self, OIDCValidationError> {
pub async fn new_for_jwks(
jwks: JWKSet<Empty>,
validation_options: ValidationOptions,
) -> Result<Self, OIDCValidationError> {
Ok(OIDCValidator {
jwks: Arc::new(jwks),
validation_options,
})
}

Expand All @@ -196,8 +209,9 @@ impl OIDCValidator {
JWT::new_encoded(token);
let decoded_token = token.decode_with_jwks(&self.jwks, Some(SignatureAlgorithm::RS256))?;
//Validate the token based on default settings.
let validation_options = ValidationOptions::default();
decoded_token.validate(validation_options).unwrap();
decoded_token
.validate(self.validation_options.clone())
.unwrap();
let claims_set = decoded_token.payload().unwrap();
let json_value = serde_json::to_value(claims_set).unwrap();
let authenticated_user: T = serde_json::from_value(json_value).unwrap();
Expand All @@ -206,10 +220,15 @@ impl OIDCValidator {

async fn fetch_discovery(uri: &str) -> Result<OIDCDiscoveryDocument, OIDCValidationError> {
let client = awc::Client::default();
client.get(uri)
.send().await
.map(|mut res| res.json::<OIDCDiscoveryDocument>()
.map_err(|err| OIDCValidationError::FailedToParseJsonResponse(err)))?.await
client
.get(uri)
.send()
.await
.map(|mut res| {
res.json::<OIDCDiscoveryDocument>()
.map_err(|err| OIDCValidationError::FailedToParseJsonResponse(err))
})?
.await
}

async fn fetch_jwks(uri: &str) -> Result<JWKSet<Empty>, OIDCValidationError> {
Expand All @@ -229,14 +248,19 @@ mod tests {

#[actix_rt::test]
async fn test_jwks_url() {
let res = OIDCValidator::new_from_issuer(String::from(TEST_ISSUER)).await;
let validation_options = ValidationOptions::default();
let res =
OIDCValidator::new_from_issuer(String::from(TEST_ISSUER), validation_options).await;
assert!(res.is_ok());
let _validator = res.expect("Cannot retrieve");
}

#[actix_rt::test]
async fn test_jwks_url_fail() {
let res = OIDCValidator::new_from_issuer(String::from("https://invalid.url")).await;
let validation_options = ValidationOptions::default();
let res =
OIDCValidator::new_from_issuer(String::from("https://invalid.url"), validation_options)
.await;
assert!(res.is_err());
}
}
17 changes: 13 additions & 4 deletions tests/extractor-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use actix_4_jwt_auth::{AuthenticatedUser, OIDCValidator, OIDCValidatorConfig};
use actix_web::dev::Service;
use actix_web::{get, http, http::header, test, App, Error};
use biscuit::ValidationOptions;
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use serde_json::json;
Expand Down Expand Up @@ -31,7 +32,10 @@ async fn test_jwt_auth_ok() -> Result<(), Error> {
//Check if spectare/oidc-token-test-service:latest is running on given test_issuer endpoint.
assert_eq!(common::check_test_idp(test_issuer.clone()).await, Ok(true));

let created_validator = OIDCValidator::new_from_issuer(test_issuer.clone()).await.unwrap();
let validation_options = ValidationOptions::default();
let created_validator = OIDCValidator::new_from_issuer(test_issuer.clone(), validation_options)
.await
.unwrap();
let validator_config = OIDCValidatorConfig {
issuer: test_issuer,
validator: created_validator,
Expand Down Expand Up @@ -95,7 +99,10 @@ async fn test_jwt_auth_expired() -> () {
//Check if spectare/oidc-token-test-service:latest is running on given test_issuer endpoint.
assert_eq!(common::check_test_idp(test_issuer.clone()).await, Ok(true));

let created_validator = OIDCValidator::new_from_issuer(test_issuer.clone()).await.unwrap();
let validation_options = ValidationOptions::default();
let created_validator = OIDCValidator::new_from_issuer(test_issuer.clone(), validation_options)
.await
.unwrap();
let validator_config = OIDCValidatorConfig {
issuer: test_issuer,
validator: created_validator,
Expand Down Expand Up @@ -140,8 +147,10 @@ async fn test_jwt_auth_invisible_not_before() -> () {
//Check if spectare/oidc-token-test-service:latest is running on given test_issuer endpoint.
assert_eq!(common::check_test_idp(test_issuer.clone()).await, Ok(true));


let created_validator = OIDCValidator::new_from_issuer(test_issuer.clone()).await.unwrap();
let validation_options = ValidationOptions::default();
let created_validator = OIDCValidator::new_from_issuer(test_issuer.clone(), validation_options)
.await
.unwrap();
let validator_config = OIDCValidatorConfig {
issuer: test_issuer,
validator: created_validator,
Expand Down

0 comments on commit bf81fc7

Please sign in to comment.