saml2

package module
v0.0.0-...-ce99e66 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2022 License: Apache-2.0 Imports: 19 Imported by: 0

README

gosaml2

Build Status GoDoc

SAML 2.0 implemementation for Service Providers based on etree and goxmldsig, a pure Go implementation of XML digital signatures.

Installation

Install gosaml2 into your $GOPATH using go get:

go get github.com/russellhaering/gosaml2

Example

See demo.go.

Supported Identity Providers

This library is meant to be a generic SAML implementation. If you find a standards compliant identity provider that it doesn't work with please submit a bug or pull request.

The following identity providers have been tested:

  • Okta
  • Auth0
  • Shibboleth
  • Ipsilon
  • OneLogin

Documentation

Index

Constants

View Source
const (
	ReasonUnsupported = "Unsupported"
	ReasonExpired     = "Expired"
)

Oft-used messages

View Source
const (
	ResponseTag                = "Response"
	AssertionTag               = "Assertion"
	EncryptedAssertionTag      = "EncryptedAssertion"
	SubjectTag                 = "Subject"
	NameIdTag                  = "NameID"
	SubjectConfirmationTag     = "SubjectConfirmation"
	SubjectConfirmationDataTag = "SubjectConfirmationData"
	AttributeStatementTag      = "AttributeStatement"
	AttributeValueTag          = "AttributeValue"
	ConditionsTag              = "Conditions"
	AudienceRestrictionTag     = "AudienceRestriction"
	AudienceTag                = "Audience"
	OneTimeUseTag              = "OneTimeUse"
	ProxyRestrictionTag        = "ProxyRestriction"
	IssuerTag                  = "Issuer"
	StatusTag                  = "Status"
	StatusCodeTag              = "StatusCode"
)
View Source
const (
	DestinationAttr  = "Destination"
	VersionAttr      = "Version"
	IdAttr           = "ID"
	MethodAttr       = "Method"
	RecipientAttr    = "Recipient"
	NameAttr         = "Name"
	NotBeforeAttr    = "NotBefore"
	NotOnOrAfterAttr = "NotOnOrAfter"
	CountAttr        = "Count"
)
View Source
const (
	NameIdFormatPersistent      = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
	NameIdFormatTransient       = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
	NameIdFormatEmailAddress    = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
	NameIdFormatUnspecified     = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
	NameIdFormatX509SubjectName = "urn:oasis:names:tc:SAML:1.1:nameid-format:x509SubjectName"

	AuthnContextPasswordProtectedTransport = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"

	AuthnPolicyMatchExact   = "exact"
	AuthnPolicyMatchMinimum = "minimum"
	AuthnPolicyMatchMaximum = "maximum"
	AuthnPolicyMatchBetter  = "better"

	StatusCodeSuccess          = "urn:oasis:names:tc:SAML:2.0:status:Success"
	StatusCodePartialLogout    = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
	StatusCodeUnknownPrincipal = "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"

	BindingHttpPost     = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
	BindingHttpRedirect = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
)
View Source
const (
	SAMLAssertionNamespace = "urn:oasis:names:tc:SAML:2.0:assertion"
	SAMLProtocolNamespace  = "urn:oasis:names:tc:SAML:2.0:protocol"
)
View Source
const (
	SubjMethodBearer = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
)

Well-known methods of subject confirmation

Variables

View Source
var (
	ErrMissingAssertion = ErrMissingElement{Tag: AssertionTag}
)

ErrMissingAssertion indicates that an appropriate assertion element could not be found in the SAML Response

Functions

func DecodeUnverifiedBaseResponse

func DecodeUnverifiedBaseResponse(encodedResponse string) (*types.UnverifiedBaseResponse, error)

DecodeUnverifiedBaseResponse decodes several attributes from a SAML response for the purpose of determining how to validate the response. This is useful for Service Providers which expose a single Assertion Consumer Service URL but consume Responses from many IdPs.

func DecodeUnverifiedLogoutResponse

func DecodeUnverifiedLogoutResponse(encodedResponse string) (*types.LogoutResponse, error)

DecodeUnverifiedLogoutResponse decodes several attributes from a SAML Logout response, without doing any verifications.

Types

type AssertionInfo

type AssertionInfo struct {
	NameID                     string
	Values                     Values
	WarningInfo                *WarningInfo
	SessionIndex               string
	AuthnInstant               *time.Time
	SessionNotOnOrAfter        *time.Time
	Assertions                 []types.Assertion
	ResponseSignatureValidated bool
}

type AuthNRequest

type AuthNRequest struct {
	ID                          string `xml:",attr"`
	Version                     string `xml:",attr"`
	ProtocolBinding             string `xml:",attr"`
	AssertionConsumerServiceURL string `xml:",attr"`

	IssueInstant time.Time `xml:",attr"`

	Destination string `xml:",attr"`
	Issuer      string
}

AuthNRequest is the go struct representation of an authentication request

type ErrInvalidValue

type ErrInvalidValue struct {
	Key, Expected, Actual string
	Reason                string
}

ErrInvalidValue indicates that the expected value did not match the received value.

func (ErrInvalidValue) Error

func (e ErrInvalidValue) Error() string

type ErrMissingElement

type ErrMissingElement struct {
	Tag, Attribute string
}

ErrMissingElement is the error type that indicates an element and/or attribute is missing. It provides a structured error that can be more appropriately acted upon.

func (ErrMissingElement) Error

func (e ErrMissingElement) Error() string

type ErrParsing

type ErrParsing struct {
	Tag, Value, Type string
}

ErrParsing indicates that the value present in an assertion could not be parsed. It can be inspected for the specific tag name, the contents, and the intended type.

func (ErrParsing) Error

func (ep ErrParsing) Error() string

type ErrSaml

type ErrSaml struct {
	Message string
	System  error
}

func (ErrSaml) Error

func (serr ErrSaml) Error() string

type ErrVerification

type ErrVerification struct {
	Cause error
}

func (ErrVerification) Error

func (e ErrVerification) Error() string

type LogoutRequest

type LogoutRequest struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol LogoutRequest"`
	ID      string   `xml:"ID,attr"`
	Version string   `xml:"Version,attr"`

	IssueInstant time.Time `xml:"IssueInstant,attr"`

	Destination string        `xml:"Destination,attr"`
	Issuer      *types.Issuer `xml:"Issuer"`

	NameID             *types.NameID `xml:"NameID"`
	SignatureValidated bool          `xml:"-"` // not read, not dumped
}

LogoutRequest is the go struct representation of a logout request

type ProxyRestriction

type ProxyRestriction struct {
	Count    int
	Audience []string
}

type RequestedAuthnContext

type RequestedAuthnContext struct {
	// The RequestedAuthnContext comparison policy to use. See the section 3.3.2.2.1
	// of the SAML 2.0 specification for details. Constants named AuthnPolicyMatch*
	// contain standardized values.
	Comparison string

	// Contexts will be passed as AuthnContextClassRefs. For example, to force password
	// authentication on some identity providers, Contexts should have a value of
	// []string{AuthnContextPasswordProtectedTransport}, and Comparison should have a
	// value of AuthnPolicyMatchExact.
	Contexts []string
}

RequestedAuthnContext controls which authentication mechanisms are requested of the identity provider. It is generally sufficient to omit this and let the identity provider select an authentication mechansim.

type SAMLServiceProvider

type SAMLServiceProvider struct {
	IdentityProviderSSOURL     string
	IdentityProviderSSOBinding string
	IdentityProviderSLOURL     string
	IdentityProviderSLOBinding string
	IdentityProviderIssuer     string

	AssertionConsumerServiceURL       string
	MultiAssertionConsumerServiceURLs []string
	ServiceProviderSLOURL             string
	ServiceProviderIssuer             string

	SignAuthnRequests              bool
	SignAuthnRequestsAlgorithm     string
	SignAuthnRequestsCanonicalizer dsig.Canonicalizer

	// RequestedAuthnContext allows service providers to require that the identity
	// provider use specific authentication mechanisms. Leaving this unset will
	// permit the identity provider to choose the auth method. To maximize compatibility
	// with identity providers it is recommended to leave this unset.
	RequestedAuthnContext   *RequestedAuthnContext
	AudienceURI             string
	IDPCertificateStore     dsig.X509CertificateStore
	SPKeyStore              dsig.X509KeyStore // Required encryption key, default signing key
	SPSigningKeyStore       dsig.X509KeyStore // Optional signing key
	NameIdFormat            string
	ValidateEncryptionCert  bool
	SkipSignatureValidation bool
	AllowMissingAttributes  bool
	Clock                   *dsig.Clock
	// contains filtered or unexported fields
}

func (*SAMLServiceProvider) AuthRedirect

func (sp *SAMLServiceProvider) AuthRedirect(w http.ResponseWriter, r *http.Request, relayState string) (err error)

AuthRedirect takes a ResponseWriter and Request from an http interaction and redirects to the SAMLServiceProvider's configured IdP, including the relayState provided, if any.

func (*SAMLServiceProvider) BuildAuthBodyPost

func (sp *SAMLServiceProvider) BuildAuthBodyPost(relayState string) ([]byte, error)

BuildAuthBodyPost builds the POST body to be sent to IDP.

func (*SAMLServiceProvider) BuildAuthBodyPostFromDocument

func (sp *SAMLServiceProvider) BuildAuthBodyPostFromDocument(relayState string, doc *etree.Document) ([]byte, error)

BuildAuthBodyPostFromDocument builds the POST body to be sent to IDP. It takes the AuthnRequest xml as input.

func (*SAMLServiceProvider) BuildAuthRequest

func (sp *SAMLServiceProvider) BuildAuthRequest() (string, error)

BuildAuthRequest builds <AuthnRequest> for identity provider

func (*SAMLServiceProvider) BuildAuthRequestDocument

func (sp *SAMLServiceProvider) BuildAuthRequestDocument(acsUrl ...string) (*etree.Document, error)

func (*SAMLServiceProvider) BuildAuthRequestDocumentNoSig

func (sp *SAMLServiceProvider) BuildAuthRequestDocumentNoSig(acsUrl ...string) (*etree.Document, error)

func (*SAMLServiceProvider) BuildAuthURL

func (sp *SAMLServiceProvider) BuildAuthURL(relayState string) (string, error)

BuildAuthURL builds redirect URL to be sent to principal

func (*SAMLServiceProvider) BuildAuthURLFromDocument

func (sp *SAMLServiceProvider) BuildAuthURLFromDocument(relayState string, doc *etree.Document) (string, error)

func (*SAMLServiceProvider) BuildAuthURLRedirect

func (sp *SAMLServiceProvider) BuildAuthURLRedirect(relayState string, doc *etree.Document) (string, error)

func (*SAMLServiceProvider) BuildLogoutBodyPostFromDocument

func (sp *SAMLServiceProvider) BuildLogoutBodyPostFromDocument(relayState string, doc *etree.Document) ([]byte, error)

BuildLogoutBodyPostFromDocument builds the POST body to be sent to IDP. It takes the LogoutRequest xml as input.

func (*SAMLServiceProvider) BuildLogoutRequestDocument

func (sp *SAMLServiceProvider) BuildLogoutRequestDocument(nameID string, sessionIndex string) (*etree.Document, error)

func (*SAMLServiceProvider) BuildLogoutRequestDocumentNoSig

func (sp *SAMLServiceProvider) BuildLogoutRequestDocumentNoSig(nameID string, sessionIndex string) (*etree.Document, error)

func (*SAMLServiceProvider) BuildLogoutResponseBodyPostFromDocument

func (sp *SAMLServiceProvider) BuildLogoutResponseBodyPostFromDocument(relayState string, doc *etree.Document) ([]byte, error)

func (*SAMLServiceProvider) BuildLogoutResponseDocument

func (sp *SAMLServiceProvider) BuildLogoutResponseDocument(status string, reqID string) (*etree.Document, error)

func (*SAMLServiceProvider) BuildLogoutResponseDocumentNoSig

func (sp *SAMLServiceProvider) BuildLogoutResponseDocumentNoSig(status string, reqID string) (*etree.Document, error)

func (*SAMLServiceProvider) BuildLogoutURLRedirect

func (sp *SAMLServiceProvider) BuildLogoutURLRedirect(relayState string, doc *etree.Document) (string, error)

func (*SAMLServiceProvider) GetEncryptionCertBytes

func (sp *SAMLServiceProvider) GetEncryptionCertBytes() ([]byte, error)

func (*SAMLServiceProvider) GetEncryptionKey

func (sp *SAMLServiceProvider) GetEncryptionKey() dsig.X509KeyStore

func (*SAMLServiceProvider) GetSigningCertBytes

func (sp *SAMLServiceProvider) GetSigningCertBytes() ([]byte, error)

func (*SAMLServiceProvider) GetSigningKey

func (sp *SAMLServiceProvider) GetSigningKey() dsig.X509KeyStore

func (*SAMLServiceProvider) Metadata

func (sp *SAMLServiceProvider) Metadata() (*types.EntityDescriptor, error)

func (*SAMLServiceProvider) MetadataWithSLO

func (sp *SAMLServiceProvider) MetadataWithSLO(validityHours int64) (*types.EntityDescriptor, error)

func (*SAMLServiceProvider) RetrieveAssertionInfo

func (sp *SAMLServiceProvider) RetrieveAssertionInfo(encodedResponse string) (*AssertionInfo, error)

RetrieveAssertionInfo takes an encoded response and returns the AssertionInfo contained, or an error message if an error has been encountered.

func (*SAMLServiceProvider) SignAuthnRequest

func (sp *SAMLServiceProvider) SignAuthnRequest(el *etree.Element) (*etree.Element, error)

SignAuthnRequest takes a document, builds a signature, creates another document and inserts the signature in it. According to the schema, the position of the signature is right after the Issuer [1] then all other children.

[1] https://docs.oasis-open.org/security/saml/v2.0/saml-schema-protocol-2.0.xsd

func (*SAMLServiceProvider) SignLogoutRequest

func (sp *SAMLServiceProvider) SignLogoutRequest(el *etree.Element) (*etree.Element, error)

func (*SAMLServiceProvider) SignLogoutResponse

func (sp *SAMLServiceProvider) SignLogoutResponse(el *etree.Element) (*etree.Element, error)

func (*SAMLServiceProvider) SigningContext

func (sp *SAMLServiceProvider) SigningContext() *dsig.SigningContext

func (*SAMLServiceProvider) Validate

func (sp *SAMLServiceProvider) Validate(response *types.Response) error

Validate ensures that the assertion passed is valid for the current Service Provider.

func (*SAMLServiceProvider) ValidateDecodedLogoutRequest

func (sp *SAMLServiceProvider) ValidateDecodedLogoutRequest(request *LogoutRequest) error

func (*SAMLServiceProvider) ValidateDecodedLogoutResponse

func (sp *SAMLServiceProvider) ValidateDecodedLogoutResponse(response *types.LogoutResponse) error

func (*SAMLServiceProvider) ValidateEncodedLogoutRequestPOST

func (sp *SAMLServiceProvider) ValidateEncodedLogoutRequestPOST(encodedRequest string) (*LogoutRequest, error)

func (*SAMLServiceProvider) ValidateEncodedLogoutResponsePOST

func (sp *SAMLServiceProvider) ValidateEncodedLogoutResponsePOST(encodedResponse string) (*types.LogoutResponse, error)

func (*SAMLServiceProvider) ValidateEncodedResponse

func (sp *SAMLServiceProvider) ValidateEncodedResponse(encodedResponse string) (*types.Response, error)

ValidateEncodedResponse both decodes and validates, based on SP configuration, an encoded, signed response. It will also appropriately decrypt a response if the assertion was encrypted

func (*SAMLServiceProvider) VerifyAssertionConditions

func (sp *SAMLServiceProvider) VerifyAssertionConditions(assertion *types.Assertion) (*WarningInfo, error)

VerifyAssertionConditions inspects an assertion element and makes sure that all SAML2 contracts are upheld.

type Values

type Values map[string]types.Attribute

Values is a convenience wrapper for a map of strings to Attributes, which can be used for easy access to the string values of Attribute lists.

func (Values) Get

func (vals Values) Get(k string) string

Get is a safe method (nil maps will not panic) for returning the first value for an attribute at a key, or the empty string if none exists.

func (Values) GetAll

func (vals Values) GetAll(k string) []string

GetAll returns all the values for an attribute at a key. Returns an empty slice in case of error of if key is not found.

func (Values) GetSize

func (vals Values) GetSize(k string) int

GetSize returns the number of values for an attribute at a key. Returns '0' in case of error or if key is not found.

type WarningInfo

type WarningInfo struct {
	OneTimeUse       bool
	ProxyRestriction *ProxyRestriction
	NotInAudience    bool
	InvalidTime      bool
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL