Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The rest of the configuration needed is generally for the decoding and mapping/propagation of Attribute data from SAML, into the IdP, and usually on to SPs, which is common to most proxy authentication scenarios.

Note

Please be aware that the issues raised by SameSite are fatal to this feature. If you have not yet deployed the filter provided as a workaround (possibly including accomodations for older Apple browsers), you will experience sporadic failures with this feature during the SAML POST back to the proxying Shibboleth IdP.

General Configuration

There are only two core requirements for this flow to operate:

...

If some form of user interface is required to perform discovery, this must be achieved by implementing that in form of a compliant Discovery service (the standard protocol is based on simple redirects, so is readily implementable).

localtab-live
Localtabgroup
Expand
titleV4.0

For simpler cases, a bean named shibboleth.authn.SAML.discoveryFunction can be defined in authn/saml-authn-config.xml to produce the entityID of the IdP to use.

localtab-live
V4
Expand
activetrue
title
titleV4.1+

For simpler cases, the idp.authn.SAML.proxyEntityID property can be set, to directly specify an IdP to use, or a bean named shibboleth.authn.SAML.discoveryFunction can be defined (using global.xml is fine) to produce the entityID of the IdP to use.

...

  • The IdP's entityID is presumed to be the same one applying to normal outbound use, but can be overridden if required.

  • The AssertionConsumerService <AssertionConsumerService> for the IdP-acting-as-SP supports only the HTTP-POST binding and is located at the path "/idp/profile/Authn/SAML2/POST/SSO".

  • Encryption is fully supported; you may not have bothered doing anything with the existing encryption key generated at install time but it will be used by default to decrypt incoming SAML and its certificate would need to be published in the metadata you give to the proxied IdP. Of course you are free not to do this and accept plaintext assertions.

  • If you wish to sign requests, you would also need to supply include the existing IdP’s usual signing certificate. Note that the primary use case for this is logout, but the proxying support doesn't include any logout integration at present. If logout is making fire, logout and proxying together is quantum physics.

Post-Processing

...

A Note About Azure

Apparently Azure enforces the underlying schema rule in SAML that the <RequesterID> element contains an actual URI. The IdP will populate this element with the identity of the downstream SP for which it is proxying authentication, and if it doesn’t happen to match Microsoft’s almost-certainly inexact determination about what constitutes a value, they reject it. If you’re proxying to Azure, you may need to set the SSO ignoreScoping profile configuration property to skip the creation of the entire <Scoping> element in the request.

It is notable that Azure happily allows the actual entityID of the SPs it connects to to contain any string value, despite that being unsafe, insecure, and of much greater consequence than the <RequesterID> element.

Post-Processing

The bulk of the configuration of this flow is actually not core to the flow's operation but the post-processing of the SAML Assertions that are returned in a successful responseresponse.

Authentication Time

By default, the AuthenticationResult created will be stamped with the AuthnInstant attribute supplied by the proxied IdP, which has implications on the policy you set for lifetime and timeout of these results. If you prefer to ignore that value and use the current time instead, you can set the SAML2.SSO profile bean’s isProxiedAuthnInstant setting to "false".

Attribute Extraction and Filtering

...

Once the results have been produced, the AttributeFilterConfiguration is applied to the results. This is a reversal of the usual filtering process of outbound data and operates with the proxying IdP itself as the "requester" and the proxied IdP as the "issuer", applying the Requester- and Issuer-based rules, respectively. It is also often desirable to apply "scope filtering" based on metadata when defining acceptance rules for scoped attributes.

If discriminating based on the issuer isn't sufficient, "Inbound" and "Outbound" policy rules are now provided for limiting policies based on the direction of the transaction.

No matter how you ultimately want to write these rules, it’s a good idea after testing to review your existing filtering policies to ensure you’re not allowing anything inbound you may not be intending to.

Example

An IdP proxying for a dedicated system with some discrete attributes might have a filter policy such as the following:

...

After that, the specific approach varies by version.

localtab-livetrue
Localtabgroup
Expand
titleV4.0

You will need to add the following to your AttributeResolverConfiguration:

Addition to attribute-resolver.xml
Code Block
languagexml
    <AttributeDefinition id="canonicalName" xsi:type="SubjectDerivedAttribute"
        forCanonicalization="true"
        principalAttributeName="eduPersonPrincipalName" />

The id there is arbitrary, it just delineates the result as a particular piece of data sourced from the proxied IdP and to be used to establish the normalized name. The forCanonicalization flag designates that the source of this is the intermediate result undergoing c14n and never data that is normally floating around the system after authentication.

Once you have that, you must then configure the attribute post-login c14n flow in the typical manner by pointing it at "canonicalName" as its source:

conf/c14n/subject-c14n.xml
Code Block
languagexml
        <!-- Remove comment tags to enable Attribute-based c14n -->
        <bean id="c14n/attribute" parent="shibboleth.PostLoginSubjectCanonicalizationFlow" />
conf/c14n/attribute-sourced-subject-c14n-config.xml
Code Block
languagexml
    <!--
    A list of attributes to resolve for normalizing the subject. For example, you might
    intend to lookup a name in a directory based on what the user entered. You can make this
    an empty list if you just want to resolve everything you normally would.
    -->
    <util:list id="shibboleth.c14n.attribute.AttributesToResolve">
        <value>canonicalName</value>
    </util:list>

    <!--
    A list of attributes to search for a value to produce as the normalized subject name.
    This will normally be something you resolve above.
    -->
    <util:list id="shibboleth.c14n.attribute.AttributeSourceIds">
        <value>canonicalName</value>
    </util:list>
Localtab live
active
Expand
titleV4.1+

With newer versions, all you have to do is to configure the attribute post-login c14n flow via properties by pointing it at "eduPersonPrincipalName" as a source. The properties to enable this are commented out in conf/c14n/subject-c14n.properties and are noted below.

conf/c14n/subject-c14n.xml
Code Block
languagexml
        <!-- Remove comment tags to enable Attribute-based c14n -->
        <bean id="c14n/attribute" parent="shibboleth.PostLoginSubjectCanonicalizationFlow" />
conf/c14n/subject-c14n.properties
Code Block
idp.c14n.attribute.attributeSourceIds = eduPersonPrincipalName
# Allows direct use of attributes via SAML proxy authn, bypasses resolver
idp.c14n.attribute.resolveFromSubject = true
idp.c14n.attribute.resolutionCondition = shibboleth.Conditions.FALSE

...

Note that as with all other profile configuration behavior, it's possible to leverage metadata extension tags to drive these settings.

Reference

Localtabgroupexpand
Localtab live
titleBeans (V4.0)

The beans defined, or expected to be defined, in authn/saml-authn-config.xml follow:

Bean ID / Type / Default

Description

shibboleth.authn.SAML.discoveryFunction

Function<ProfileRequestContext,String>

Used to derive entityID of IdP to use if Discovery is not being performed prior to flow operation

shibboleth.authn.SAML.externalAuthnPath

String

servletRelative:/Authn/SAML2/POST/SSO

Spring Web Flow redirection expression for the IdP's AssertionConsumerService

shibboleth.authn.SAML.externalAuthnPathStrategy

Function<ProfileRequestContext,String>

Optional function bean to override the redirection expression to use for the protected resource

shibboleth.authn.SAML.resultCachingPredicate

Predicate<ProfileRequestContext>

shibboleth.Conditions.TRUE

Bean that can be defined to control whether to preserve the authentication result in an IdP session

shibboleth.authn.SAML.addDefaultPrincipals

Boolean

false

Whether to add the content of the supportedPrincipals property of the underlying flow descriptor to the resulting Subject

shibboleth.authn.SAML.attributeExtractionStrategy

Function<ProfileRequestContext,Collection<IdPAttribute>>

A custom function to produce additional IdPAttributes from the SAML response

localtab-live
true
Expand
titleBeans (V4.1+)

The following beans if needed may be defined in global.xml (or if desired the legacy authn/saml-authn-config.xml file may be used or created):

Bean ID / Type

Default

Description

shibboleth.authn.SAML.discoveryFunction

Function<ProfileRequestContext,String>


Used to derive entityID of IdP to use if not using a static property and IdP Discovery is not performed prior to flow operation

shibboleth.authn.SAML.externalAuthnPathStrategy

Function<ProfileRequestContext,String>


Optional function bean to override the redirection expression to use for the protected resource

shibboleth.authn.SAML.resultCachingPredicate

Predicate<ProfileRequestContext>

true

Bean that can be defined to control whether to preserve the authentication result in an IdP session

shibboleth.authn.SAML.attributeExtractionStrategy

Function<ProfileRequestContext,Collection<IdPAttribute>>


Optional custom function to produce additional IdPAttributes from the SAML response

Localtab live
active
Optional bean ID of Function<ProfileRequestContext,MessageHandlerException> to run just prior to AuthnRequest signing/encoding step
Expand
titleSAML-Specific Properties (V4.1+)

The properties specific to this flow defined in authn/authn.properties are:

Name / Default

Description

idp.authn.SAML.externalAuthnPath

servletRelative:/Authn

/SAML2/POST/SSO

Spring Web Flow redirection expression for the IdP's AssertionConsumerService

idp.authn.SAML.proxyEntityID

Statically-defined entityID of IdP to use for authentication

idp.authn.SAML.outboundMessageHandlerFunction

/SAML2/POST/SSO

Spring Web Flow redirection expression for the IdP's AssertionConsumerService

idp.authn.SAML.

inboundMessageHandlerFunctionOptional bean ID of Function<ProfileRequestContext,MessageHandlerException> to run at the late stages of Response decoding/processing

proxyEntityID

Statically-defined entityID of IdP to use for authentication

idp.authn.SAML.assertionValidator

Optional bean ID of AssertionValidator to run

Expand
titleGeneral Properties (V4.1+)

The general properties configuring this flow via authn/authn.properties are:

Name

Default

Description

idp.authn.SAML.order

1000

Flow priority relative to other enabled login flows (lower is "higher" in priority)

idp.authn.SAML.nonBrowserSupported

false

Whether the flow should handle non-browser request profiles (e.g., ECP)

idp.authn.SAML.passiveAuthenticationSupported

true

Whether the flow allows for passive authentication

idp.authn.SAML.forcedAuthenticationSupported

true

Whether the flow supports forced authentication

idp.authn.SAML.proxyRestrictionsEnforced

%{idp.authn.enforceProxyRestrictions:true}

Whether the flow enforces upstream IdP-imposed restrictions on proxying

idp.authn.SAML.proxyScopingEnforced

true

Whether the flow considers itself to be proxying, and therefore enforces SP-signaled restrictions on proxying

idp.authn.SAML.discoveryRequired

true

Whether to invoke IdP-discovery prior to running flow

idp.authn.SAML.lifetime

%{idp.authn.defaultLifetime:PT1H}

Lifetime of results produced by this flow

idp.authn.SAML.inactivityTimeout

%{idp.authn.defaultTimeout:PT30M}

Inactivity timeout of results produced by this flow

idp.authn.SAML.reuseCondition

shibboleth.Conditions.TRUE

Bean ID of Predicate<ProfileRequestContext> controlling result reuse for SSO

idp.authn.SAML.activationCondition

shibboleth.Conditions.TRUE

Bean ID of Predicate<ProfileRequestContext> determining whether flow is usable for request

idp.authn.SAML.subjectDecorator


Bean ID of BiConsumer<ProfileRequestContext,Subject> for subject customization

idp.authn.SAML.supportedPrincipals

(see below)

Comma-delimited list of protocol-specific Principal strings associated with flow

idp.authn.SAML.addDefaultPrincipals

false

Whether to auto-attach the preceding set of Principal objects to each Subject produced by this flow

While the default principal support is a typical password-centric set, in most cases the addDefaultPrincipals property is left false and the values used in responses will be mapped from the value supplied by the proxied IdP. However, to handle requests properly, the supportedPrincipals property may need to be adjusted to account for the possible values that SPs should be allowed to request.

localtab-live
Expand
titleFlow Descriptor XML (V4.1+)

To replace the internally defined flow descriptor bean, the following XML is required:

Code Block
languagexml
<util:list id="shibboleth.AvailableAuthenticationFlows">
 
    <bean p:id="authn/SAML" parent="shibboleth.AuthenticationFlow"
            p:order="%{idp.authn.SAML.order:1000}"
            p:nonBrowserSupported="%{idp.authn.SAML.nonBrowserSupported:false}"
            p:passiveAuthenticationSupported="%{idp.authn.SAML.passiveAuthenticationSupported:true}"
            p:forcedAuthenticationSupported="%{idp.authn.SAML.forcedAuthenticationSupported:true}"
            p:proxyRestrictionsEnforced="%{idp.authn.SAML.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}"
            p:proxyScopingEnforced="%{idp.authn.SAML.proxyScopingEnforced:true}"
            p:discoveryRequired="%{idp.authn.SAML.discoveryRequired:true}"
            p:lifetime="%{idp.authn.SAML.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
            p:inactivityTimeout="%{idp.authn.SAML.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
            p:reuseCondition-ref="#{'%{idp.authn.SAML.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
            p:activationCondition-ref="#{'%{idp.authn.SAML.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
            p:subjectDecorator-ref="#{getObject('%{idp.authn.SAML.subjectDecorator:}'.trim())}">
        <property name="supportedPrincipalsByString">
            <bean parent="shibboleth.CommaDelimStringArray"
                c:_0="#{'%{idp.authn.SAML.supportedPrincipals:}'.trim()}" />
        </property>
    </bean>
 
</util:list>

In older versions and upgraded systems, this list is defined in conf/authn/general-authn.xml. In V4.1+, no default version of the list is provided and it may simply be placed in conf/global.xml if needed.

...