Crates.io | samael |
lib.rs | samael |
version | |
source | src |
created_at | 2020-02-23 20:48:21.465107+00 |
updated_at | 2025-01-15 16:24:04.827691+00 |
description | A SAML2 library for Rust |
homepage | |
repository | https://github.com/njaremko/samael |
max_upload_size | |
id | 211847 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
This is a SAML2 library for rust.
This is a work in progress. Pull Requests are welcome.
Current Features:
The "xmlsec"
feature flag adds basic support for verifying and signing SAML messages. We're using a modified copy of rust-xmlsec library (bindings to xmlsec1 library).
If you want to use the "xmlsec"
feature, you'll need to install the following C libs:
We use nix to faciliate reproducible builds of samael
.
It will ensure you have the required libraries installed in a way that won't cause any issues with the rest of your system.
If you want to take advantage of this, you'll need to put in a little bit of work.
# Add ~/.nix-profile/bin to your path first
nix profile install nixpkgs#direnv
nix profile install nixpkgs#cachix
cachix use nix-community
to enable a binary cache for the rust toolchain (otherwise you'll build the rust toolchain from scratch)cd
into this repo and run direnv allow
and nix-direnv-reload
Just run nix build
If you followed the above instructions, just cd
-ing into the directory will setup a reproducible dev environment,
but if you don't want to install direnv
, then just run nix develop
.
From their you can build as normal:
cargo build --features xmlsec
cargo test --features xmlsec
You'll need these dependencies for this example
[dependencies]
tokio = { version = "1.28.1", features = ["full"] }
samael = { version = "0.0.12", features = ["xmlsec"] }
warp = "0.3.5"
reqwest = "0.11.18"
openssl = "0.10.52"
openssl-probe = "0.1.5"
Here is some sample code using this library:
use samael::metadata::{ContactPerson, ContactType, EntityDescriptor};
use samael::service_provider::ServiceProviderBuilder;
use std::collections::HashMap;
use std::fs;
use warp::Filter;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
openssl_probe::init_ssl_cert_env_vars();
let resp = reqwest::get("https://samltest.id/saml/idp")
.await?
.text()
.await?;
let idp_metadata: EntityDescriptor = samael::metadata::de::from_str(&resp)?;
let pub_key = openssl::x509::X509::from_pem(&fs::read("./publickey.cer")?)?;
let private_key = openssl::rsa::Rsa::private_key_from_pem(&fs::read("./privatekey.pem")?)?;
let sp = ServiceProviderBuilder::default()
.entity_id("".to_string())
.key(private_key)
.certificate(pub_key)
.allow_idp_initiated(true)
.contact_person(ContactPerson {
sur_name: Some("Bob".to_string()),
contact_type: Some(ContactType::Technical.value().to_string()),
..ContactPerson::default()
})
.idp_metadata(idp_metadata)
.acs_url("http://localhost:8080/saml/acs".to_string())
.slo_url("http://localhost:8080/saml/slo".to_string())
.build()?;
let metadata = sp.metadata()?.to_string()?;
let metadata_route = warp::get()
.and(warp::path("metadata"))
.map(move || metadata.clone());
let acs_route = warp::post()
.and(warp::path("acs"))
.and(warp::body::form())
.map(move |s: HashMap<String, String>| {
if let Some(encoded_resp) = s.get("SAMLResponse") {
let t = sp
.parse_base64_response(encoded_resp, Some(&["a_possible_request_id"]))
.unwrap();
return format!("{:?}", t);
}
format!("")
});
let saml_routes = warp::path("saml").and(acs_route.or(metadata_route));
warp::serve(saml_routes).run(([127, 0, 0, 1], 8080)).await;
Ok(())
}