Versions Compared

Key

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

Current File(s): conf/authn/x509-authn-config.xml, (edit-)webapp/WEB-INF/web.xml, (edit-)webapp/x509-prompt.jsp, authn/authn.properties (V4.1+)
Format: Native Spring, Properties (V4.1+)

Table of Contents

Overview

The authn/X509 login flow leverages any surrounding mechanism you have available for TLS client certificate authentication, provided the standard servlet request attribute ("javax.servlet.request.X509Certificate") is populated. By default, this flow is configured without support for advanced authentication controls like passive or forced authentication since this is not generally possible with client certificate authentication.

The result of this flow is a Java Subject containing an X500Principal derived from the subject of the certificate, and the certificate is optionally added as a public credential of the Subject. Note that no actual "username" is produced; rather, a suitable post-login Subject Canonicalization flow must be enabled/configured to pull a suitable principal name out of the Subject.

This flow is implemented as a special case of the External flow that happens to use a supplied servlet to implement the External contract that supports extraction of the certificate from the request. Rather than customizing this flow, use the External flow directly to do more advanced things.

Note that if you have a web server that is configured to perform the certificate evaluation for you and populate a header or variable with the "username" to use based on the certificate, you almost certainly will want to use the RemoteUser flow instead. This flow pulls in the certificate as the primary result of the authentication and relies on downstream logic (often the x500 subject c14n flow) to get a username out of it.

Enabling Module (V4.1+)

For V4.1+, configuring and using this feature requires that you first enable the "idp.authn.X509" module if it isn't already enabled. Systems upgraded from older releases generally come pre-enabled due to the prior state of the configuration tree.

Code Block
(Windows)
C:\opt\shibboleth-idp> bin\module.bat -t idp.authn.X509 || bin\module.bat -e idp.authn.X509
 
(Other)
$ bin/module.sh -t idp.authn.X509 || bin/module.sh -e idp.authn.X509

General Configuration

Localtabgroup

Localtab-live
titleV4.0

Use conf/authn/x509-authn-config.xml to configure this flow.

The shibboleth.authn.X509.externalAuthnPath bean is the flow redirection path to either a JSP page allowing an explicit prompt for certificate authentication (and other messaging to the user), or directly to the authentication servlet, skipping the UI (which is at /Authn/X509). These are context-relative locations, and you can use any JSP page you choose. It can be modified if needed, but in most cases modifying this to anything but one of those two choices means the External flow is likely a better choice to use.

Localtab-live
activetrue
titleV4.1+

Most of the usual options are available via authn/authn.properties, and some more advanced cases will require defining/adjusting bean definitions in authn/x509-authn-config.xml.

The idp.authn.X509.externalAuthnPath property is the flow redirection path to either a JSP page allowing an explicit prompt for certificate authentication (and other messaging to the user), or directly to the authentication servlet, skipping the UI (which is at /Authn/X509). These are context-relative locations, and you can use any JSP page you choose. It can be modified if needed, but in most cases modifying this to anything but one of those two choices means the External flow is likely a better choice to use.

You can make the location dynamic via a bean of type Function<ProfileRequestContext,String> named shibboleth.authn.X509.externalAuthnPathStrategy

The shibboleth.authn.X509.ClassifiedMessageMap bean is a map of error messages to classified error conditions that isn't generally used with this handler because it usually won't return with any contextual details, but there is a default mapping supplied that signals fall-through to other login flows if no certificate is found or the certificate fails optional validation. This is done by remapping those specific error events into a "ReselectFlow" event.

The servlet that implements the authentication for this flow is configured by webapp/WEB-INF/web.xml and can be given a "trustEngine" context parameter that identifies a Spring bean ID of an OpenSAML TrustEngine that should be used to validate the client certificate chain. The best spot to define such a bean is usually conf/global.xml, as it needs to be in the root Spring context for the servlet to access it. Of course, it's often simpler and more common to do this validation using the web server itself, although that's less flexible.

An example of a PKIX-based TrustEngine declaration follows. The bean ID would need to be supplied in web.xml as the "trustEngine" context paramater to the servlet.

Code Block
languagexml
titleglobal.xml
<bean id="my.X509AuthnTrustEngine" parent="shibboleth.StaticPKIXTrustEngine"
	p:certificates="%{idp.home}/credentials/rootca.pem"
	p:checkNames="false"
	p:verifyDepth="1" />

The servlet also supports a boolean parameter, "saveCertificateToCredentialSet", which can be set to false to prevent the preservation of the certificate in the resulting credentials to save space if it won't be used.

As always, if editing web.xml, make sure to copy it to edit-webapp/WEB-INF first and make any changes to that copy.

Reference

FDXML

Localtabgroup

Localtab-live
titleBeans (V4.0)

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

Bean ID / TypeDefaultDescription

shibboleth.authn.X509.externalAuthnPath

String

contextRelative:x509-prompt.jsp

Spring Web Flow redirection expression for the protected resource

shibboleth.authn.X509.externalAuthnPathStrategy

Function<ProfileRequestContext,String>

A constant function returning the bean value above.A function that returns the redirection expression to use for the protected resource

shibboleth.authn.X509.ClassifiedMessageMap

Map<String,List<String>>

(see file)A map between defined error/warning conditions and events and implementation-specific message fragments to map to them.

shibboleth.authn.X509.resultCachingPredicate

Predicate<ProfileRequestContext>


An optional bean that can be defined to control whether to preserve the authentication result in an IdP session

shibboleth.authn.X509.addDefaultPrincipals

Boolean

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

Localtab-live
titleBeans (V4.1+)

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

Bean ID / TypeDefaultDescription

shibboleth.authn.X509.externalAuthnPathStrategy

Function<ProfileRequestContext,String>

A constant function returning the bean value above.A function that returns the redirection expression to use for the protected resource

shibboleth.authn.X509.ClassifiedMessageMap

Map<String,List<String>>

(see file)A map between defined error/warning conditions and events and implementation-specific message fragments to map to them.

shibboleth.authn.X509.resultCachingPredicate

Predicate<ProfileRequestContext>


An optional bean that can be defined to control whether to preserve the authentication result in an IdP session

Localtab-live
activetrue
titleProperties (V4.1+)

The flow-specific properties usable via authn/authn.properties are:

NameDefaultDescription
idp.authn.X509.externalAuthnPathcontextRelative:x509-prompt.jspSpring Web Flow redirection expression for the protected resource

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

NameDefaultDescription
idp.authn.X509.order1000Flow priority relative to other enabled login flows (lower is "higher" in priority)
idp.authn.X509.nonBrowserSupportedfalseWhether the flow should handle non-browser request profiles (e.g., ECP)
idp.authn.X509.passiveAuthenticationSupportedfalseWhether the flow allows for passive authentication
idp.authn.X509.forcedAuthenticationSupportedfalseWhether the flow supports forced authentication
idp.authn.X509.proxyRestrictionsEnforced%{idp.authn.enforceProxyRestrictions:true}Whether the flow enforces upstream IdP-imposed restrictions on proxying
idp.authn.X509.proxyScopingEnforcedfalseWhether the flow considers itself to be proxying, and therefore enforces SP-signaled restrictions on proxying
idp.authn.X509.discoveryRequiredfalseWhether to invoke IdP-discovery prior to running flow
idp.authn.X509.lifetime%{idp.authn.defaultLifetime:PT1H}Lifetime of results produced by this flow
idp.authn.X509.inactivityTimeout%{idp.authn.defaultTimeout:PT30M}Inactivity timeout of results produced by this flow
idp.authn.X509.reuseConditionshibboleth.Conditions.TRUEBean ID of Predicate<ProfileRequestContext> controlling result reuse for SSO
idp.authn.X509.activationConditionshibboleth.Conditions.TRUEBean ID of Predicate<ProfileRequestContext> determining whether flow is usable for request
idp.authn.X509.subjectDecorator
Bean ID of BiConsumer<ProfileRequestContext,Subject> for subject customization
idp.authn.X509.supportedPrincipals(see below)Comma-delimited list of protocol-specific Principal strings associated with flow
idp.authn.X509.addDefaultPrincipalstrueWhether to auto-attach the preceding set of Principal objects to each Subject produced by this flow

As a non-password based flow, the supportedPrincipals property defaults to the following XML:

Code Block
languagexml
collapsetrue
<list>
    <bean parent="shibboleth.SAML2AuthnContextClassRef"
        c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:X509" />
    <bean parent="shibboleth.SAML2AuthnContextClassRef"
        c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient" />
    <bean parent="shibboleth.SAML1AuthenticationMethod"
        c:method="urn:ietf:rfc:2246" />
</list>

In property form, this is expressed as (note the trailing commas):

Code Block
idp.authn.X509.supportedPrincipals = \
    saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:X509, \
    saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient, \
    saml1/urn:ietf:rfc:2246

Localtab

id
-live
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/X509" parent="shibboleth.AuthenticationFlow"
            p:order="%{idp.authn.X509.order:1000}"
            p:nonBrowserSupported="%{idp.authn.X509.nonBrowserSupported:false}"
            p:passiveAuthenticationSupported="%{idp.authn.X509.passiveAuthenticationSupported:false}"
            p:forcedAuthenticationSupported="%{idp.authn.X509.forcedAuthenticationSupported:false}"
            p:proxyRestrictionsEnforced="%{idp.authn.X509.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}"
            p:proxyScopingEnforced="%{idp.authn.X509.proxyScopingEnforced:false}"
            p:discoveryRequired="%{idp.authn.X509.discoveryRequired:false}"
            p:lifetime="%{idp.authn.X509.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
            p:inactivityTimeout="%{idp.authn.X509.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
            p:reuseCondition-ref="#{'%{idp.authn.X509.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
            p:activationCondition-ref="#{'%{idp.authn.X509.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
            p:subjectDecorator-ref="#{getObject('%{idp.authn.X509.subjectDecorator:}'.trim())}">
        <property name="supportedPrincipalsByString">
            <bean parent="shibboleth.CommaDelimStringArray"
                c:_0="#{'%{idp.authn.X509.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.

Notes

Note that this flow is configured by default without support for non-browser profiles (namely ECP) because the X509Internal flow is a better choice when a browser isn't required. It eliminates the extra redirects (and the optional HTML UI) used by this flow.