Search
K

SAML app

The Maverics Identity Orchestrator can be used as an IDP to protect SAML apps.
To define SAML type apps the samlProvider must be defined.

Config Options

Name

name is a unique identifier for the app.

Type

type represents the application type. When defining SAML apps, the type should be saml.

Audience

audience is a unique identifier of the application. The audience value is typically a URL, and it should match the Issuer field provided by the SAML service provider.

Consumer Service URL

consumerServiceURL is the URL where SAML responses will be sent.

IDP Initiated Login

The idpInitiatedLogin key is an optional configuration which when specified will enable the auth provider to perform IDP initiated login to the client.

Login URL

loginURL is the endpoint that the user will visit from their browser to initiate the IDP login flow. This endpoint needs to be unique on the Orchestrator.

Relay State URL

relayStateURL is the endpoint that gets passed to the service provider and is intended to be the landing page for the user after the authentication flow is complete.

Duration

duration the time in seconds which the SAML assertions are valid for. This is an optional field, and if a value is not defined, a duration of five minutes (300 seconds) will be used.

NameID Format

nameIDFormat is an optional field used to define the NameID Format that will be used in the SAML assertion. When not defined, a value of 'urn:oasis:names:tc:SAML:1.0:nameid-format:unspecified' will be used. If a NameIDPolicy is defined on the SAML Authentication request, it must match the NameID Format defined on the client. For more details on NameID Format, please see section 2.2, 3.4.1, and 8.3 of the SAML spec.

Request Verification

requestVerification is a mandatory configuration, and it will either hold the public key used to validate the signature of incoming requests, or it will disable request signing verification.

Certificate

certificate is the RSA x509 certificate, and will be used to verify the signatures of incoming requests. It may be defined inline or with a secret provider. It must be RSA compatible. Currently this auth provider only supports SHA-256 for request signing and digest algorithm.

Skip Verification

skipVerification is a boolean value and is used when the client does not want to validate the signatures of incoming requests.

Authentication

authentication defines how users are authenticated for this app.

IDPs

idps lists the IDPs which will be used to authenticate the user.

IsAuthenticated Service Extension

isAuthenticatedSE is an optional Service Extension that can be used to override the default behavior that determines if a user is already authenticated. This extension must be used with authenticateSE.

Authenticate Service Extension

authenticateSE is an optional Service Extension used to take control of how authentication will be done. This extension must be used with isAuthenticatedSE.

Attribute Providers

The attrProviders is an optional configuration for an identity system or data store from which the SAMLProvider may retrieve additional attributes used in claimsMapping.

Connector

Connector is a reference to the name of the defined connector which will be used as an attribute provider.

usernameMapping

The usernameMapping configuration makes sure the Attribute Provider (i.e. LDAP Connector) has the correct attribute it needs to successfully query for the user's attributes. It specifies the attribute used to look up user attributes from the defined attribute provider.

Encryption

encryption is an optional configuration used for encrypting the SAML assertion.

Key Encrypt Method

keyEncryptMethod configures the encryption method for encrypting the symmetric key which is used to encrypt the assertion. Currently, we support two values here which are RSA_OAEP and RSA-1_5.
RSA-1_5 is not recommended according to the XML encryption spec due to security risks associated with the algorithm.

Data Encrypt Method

dataEncryptMethod configures the encryption method for encrypting the actual data of the assertion. Valid values are AES128CBC, AES192CBC, and AES256CBC.

Digest Method

digestMethod is the message digest algorithm use to compute a message digest as part of the encryption process. Valid values are SHA256, and SHA512.

Certificate

certificate is the PEM encoded string that can be defined inline or via a secret provider. This certificate is typically retrieved from the Service Provider.

Claims Mapping

claimsMapping defines how to map attributes from the session to a SAML assertion.

Build Claims Service Extensions

buildClaimsSE is an optional Service Extension that can customize which attributes will be added to the SAML 2.0 AttributeStatement.
Only a subset of data types can be used as attribute values. The following builtin data types are supported as attribute values: bool, int, int8, int32, int64, float32, float64, and string.

Examples

Basic SAML App Config Example

apps:
- name: exampleSAMLApp
type: saml
audience: https://app.enterprise.com
consumerServiceURL: https://app.enterprise.com/acs
idpInitiatedLogin:
loginURL: https://maverics.sonarsystems.com/login/exampleSAMLApp
relayStateURL: https://app.enterprise.com/index.html
duration: 300
nameIDFormat: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
requestVerification:
certificate: <appSigningCertificate>
authentication:
idps:
- azure
attrProviders:
- connector: ldap
usernameMapping: azure.email
encryption:
keyEncryptMethod: RSA_OAEP
dataEncryptMethod: AES256CBC
digestMethod: SHA256
certificate: <encryptionCert>
claimsMapping:
id: azure.name
email: azure.email
lastName: azure.surname
groups: ldap.groupMembership

SAML App With Service Extension

apps:
- name: exampleSAMLApp
type: saml
audience: https://app.enterprise.com
consumerServiceURL: https://app.enterprise.com/acs
duration: 300
requestVerification:
certificate: <appSigningCertificate>
authentication:
isAuthenticatedSE:
funcName: IsAuthenticated
file: /etc/maverics/extensions/auth.go
authenticateSE:
funcName: Authenticate
file: /etc/maverics/extensions/auth.go
attrProviders:
- connector: ldap
usernameMapping: azure.email
buildClaimsSE:
funcName: BuildClaims
file: /etc/maverics/extensions/auth.go
/etc/maverics/extensions/auth.go
package main
import (
"net/http"
"github.com/strata-io/service-extension/orchestrator"
)
func IsAuthenticated(api orchestrator.Orchestrator, _ http.ResponseWriter, _ *http.Request) bool {
logger := api.Logger()
logger.Debug("se", "determining if user is authenticated")
session, err := api.Session()
if err != nil {
logger.Error("se", "unable to retrieve session", "error", err.Error())
return false
}
isAzureAuth, err := session.GetString("azure.authenticated")
if err != nil {
logger.Error("se", "unable to retrieve attribute 'azure.authenticated'", "error", err)
return false
}
if isAzureAuth == "true" {
return true
}
return false
}
func Authenticate(api orchestrator.Orchestrator, rw http.ResponseWriter, req *http.Request) {
logger := api.Logger()
logger.Info("se", "authenticating user")
azureIDP, err := api.IdentityProvider("azure")
if err != nil {
logger.Error(
"se", "failed to retrieve Azure IDP",
"error", err.Error(),
)
http.Error(
rw,
http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError,
)
return
}
azureIDP.Login(rw, req)
}
func BuildClaims(api orchestrator.Orchestrator, _ http.ResponseWriter, _ *http.Request) (map[string]any, error) {
logger := api.Logger()
logger.Info("se", "building custom claims")
session, err := api.Session()
if err != nil {
logger.Error("se", "unable to retrieve session", "error", err.Error())
return nil, err
}
name, _ := session.GetString("azure.email")
firstName, _ := session.GetString("azure.givenname")
lastName, _ := session.GetString("azure.surname")
return map[string]any{
"name": name,
"firstName": firstName,
"lastName": lastName,
}, nil
}