Skip to content

jmpesp/samael

 
 

Repository files navigation

Samael

Crates.io MIT licensed

This is a SAML2 library for rust.

This is a work in progress. Pull Requests are welcome.

Current Features:

  • Serializing and Deserializing SAML messages
  • IDP-initiated SSO
  • SP-initiated SSO Redirect-POST binding
  • Helpers for validating SAML assertions
    • Encrypted assertions aren't supported yet
  • Verify SAMLRequest (AuthnRequest) message signatures
  • Create signed SAMLResponse (Response) messages

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:

  • libiconv
  • libtool
  • libxml2
  • libxslt
  • libclang
  • openssl
  • pkg-config
  • xmlsec1

Build instructions

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.

  1. Install nix
  2. Install direnv and cachix
    # Add ~/.nix-profile/bin to your path first
    nix profile install nixpkgs#direnv
    nix profile install nixpkgs#cachix
    
  3. Run cachix use nix-community to enable a binary cache for the rust toolchain (otherwise you'll build the rust toolchain from scratch)
  4. cd into this repo and run direnv allow and nix-direnv-reload
  5. Install the direnv VS Code extension

Building the library

Just run nix build

Entering a dev environment

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

How do I use this library?

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: