Versions Compared

Key

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

...

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

  • The <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 include the 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.

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 responseprocessing of the SAML Assertions that are returned in a successful response.

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 transactionon 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:

...

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

Optional bean ID of Function<ProfileRequestContext,MessageHandlerException> to run just prior to AuthnRequest signing/encoding step

idp.authn.SAML.inboundMessageHandlerFunction

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

idp.authn.SAML.assertionValidator

Optional bean ID of AssertionValidator to run

...

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.

...