RemoteUserAuthnConfiguration

Current File(s): conf/authn/authn.properties
Format: Properties

Overview

The authn/RemoteUser login flow relies on whatever container-based mechanism you have available (HTTP BASIC auth, LDAP, Kerberos, other SSO systems, etc.). By default, this flow is configured without support for advanced authentication controls like passive or forced authentication. In most cases, implementing support for those features in conjunction with other SSO systems should be done with the External flow.

This flow is actually 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 identity from the request. Rather than customizing this flow, use the External flow itself if you need to do other things instead of or in addition to this behavior.

General Configuration

Use authn/authn.properties to configure this flow.

Note for Upgraded Systems

Previous versions of the software relied on settings in web.xml to enable the required servlet and adjust its behavior, but this has been supplanted by an automatic registration process that allows the servlet to be registered at runtime and the settings controlled with Spring, allowing use of properties to control behavior.

Upgraded systems will continue to function as before, but new installs will depend solely on a single <context-param> defined in web.xml to enable the servlet that supports this feature, as discussed below.

Related, the old file conf/authn/remoteuser-authn-config.xml is now supported only for compatibility and generally not installed or needed going forward.

The servlet that implements the authentication for this flow can be configured to support arbitrary headers or request attributes instead of or in addition to the REMOTE_USER reserved CGI variable (the identity of the requester as established by the web server / container, which Java exposes in the Servlet API with the getRemoteUser method). By default, it supports only the "real" REMOTE_USER value exposed via that API (this does not include headers named to emulate it, a very poor practice due to the potential for confusion).

The following properties are supported (these are all new in V5):

  • idp.authn.RemoteUser.checkRemoteUser (true or false)

    • whether to look for a principal name in REMOTE_USER

  • idp.authn.RemoteUser.checkAttributes (comma-delimited list of request attribute names)

    • servlet request attribute(s) to search for a principal name, instead of or in addition to REMOTE_USER

  • idp.authn.RemoteUser.checkHeaders (comma-delimited list of request header names)

    • servlet request header(s) to search for a principal name, instead of or in addition to REMOTE_USER

  • idp.authn.RemoteUser.subjectAttribute (name of request attribute)

    • single request attribute to check for a Java Subject to use for the authentication result

  • idp.authn.RemoteUser.authnMethodHeader (name of request header)

    • request header(s) to check for "method" strings to attach to Java subject as custom principals

  • idp.authn.RemoteUser.authnAuthorityHeader (name of request header)

    • request header(s) to check for URIs to attach to Java subject as proxied authenticating authorities

The algorithm of the servlet is roughly:

  1. If idp.authn.RemoteUser.subjectAttribute is set, check it for a Java Subject to use. If found, it will be returned through the External Authentication interface and all the other settings are ignored.

  2. Otherwise, check for a principal name as directed by the settings, in REMOTE_USER, attributes, and headers (in that order). If not found, authentication fails.

  3. If idp.authn.RemoteUser.authnMethodHeader is set, check each value to see if the associated login flow supports a custom Principal matching the value in the header, and if so, attach that Principal to the Subject returned through the External Authentication interface. Note that if the header contains a value not supported by the associated login flow, it will be logged, but otherwise not impact the success of this flow. By the time this feature is executing, it's already a given that the result was successful.

If you need something different from this, your best option is to use the External login flow and possibly adapt the existing servlet as an example to copy from for your own purposes. In all respects, this flow is simply a more concrete use of the External flow.

The idp.authn.RemoteUser.externalAuthnPath property defines the flow redirection path to the resource that's used to pick up the container-established identity, by default a context-relative location. It can be modified if needed but should generally be left alone.

Reference

The following beans are not generally needed, but may be defined in global.xml if desired.

Bean ID / Type

Default

Description

Bean ID / Type

Default

Description

shibboleth.authn.RemoteUser.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.RemoteUser.resultCachingPredicate

Predicate<ProfileRequestContext>

 

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

shibboleth.authn.RemoteUser.ClassifiedMessageMap

Map<String,Collection<String>>

Remaps NoCredentials and InvalidCredentials into ReselectFlow for fall-through behavior

Optional remapping of exception messages or events into specific Spring Web Flow events.

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

Name

Default

Description

Name

Default

Description

idp.authn.RemoteUser.externalAuthnPath

contextRelative:Authn/RemoteUser

Spring Web Flow redirection expression for the protected resource

idp.authn.RemoteUser.matchExpression

 

Regular expression to match username agains

idp.authn.RemoteUser.checkRemoteUser

true

Whether to check for a username in REMOTE_USER

idp.authn.RemoteUser.checkAttributes

 

Comma-delimited list of servlet request attributes to check for a username

idp.authn.RemoteUser.checkHeaders

 

Comma-delimited list of request headers to check for a username

idp.authn.RemoteUser.subjectAttribute

 

Name of a servlet request attribute to check for a Java Subject to bypass the rest of the servlet’s behavior

idp.authn.RemoteUser.authnMethodHeader

 

Name of a request header to check for a compatible custom Principal value to attach to the Subject

idp.authn.RemoteUser.authnAuthorityHeader

 

Name of a header to check for the name(s) of any proxied IdPs to include in the Subject

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

Name

Default

Description

Name

Default

Description

idp.authn.RemoteUser.order

1000

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

idp.authn.RemoteUser.nonBrowserSupported

false

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

idp.authn.RemoteUser.passiveAuthenticationSupported

false

Whether the flow allows for passive authentication

idp.authn.RemoteUser.forcedAuthenticationSupported

false

Whether the flow supports forced authentication

idp.authn.RemoteUser.proxyRestrictionsEnforced

%{idp.authn.enforceProxyRestrictions:true}

Whether the flow enforces upstream IdP-imposed restrictions on proxying

idp.authn.RemoteUser.proxyScopingEnforced

false

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

idp.authn.RemoteUser.discoveryRequired

false

Whether to invoke IdP-discovery prior to running flow

idp.authn.RemoteUser.lifetime

%{idp.authn.defaultLifetime:PT1H}

Lifetime of results produced by this flow

idp.authn.RemoteUser.inactivityTimeout

%{idp.authn.defaultTimeout:PT30M}

Inactivity timeout of results produced by this flow

idp.authn.RemoteUser.reuseCondition

shibboleth.Conditions.TRUE

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

idp.authn.RemoteUser.activationCondition

shibboleth.Conditions.TRUE

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

idp.authn.RemoteUser.subjectDecorator

 

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

idp.authn.RemoteUser.supportedPrincipals

(see below)

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

idp.authn.RemoteUser.addDefaultPrincipals

true

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

Most of the flows, including this one, default to describing themselves in terms of "password"-based authentication, so the supportedPrincipals property defaults to the following XML:

<list> <bean parent="shibboleth.SAML2AuthnContextClassRef" c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" /> <bean parent="shibboleth.SAML2AuthnContextClassRef" c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" /> <bean parent="shibboleth.SAML1AuthenticationMethod" c:method="urn:oasis:names:tc:SAML:1.0:am:password" /> </list>

In property form, this is expressed as (note especially the trailing commas, which MUST be there):

idp.authn.RemoteUser.supportedPrincipals = \ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \ saml1/urn:oasis:names:tc:SAML:1.0:am:password

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

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

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

Notes

This flow is configured by default without support for non-browser profiles (namely ECP) because the RemoteUserInternal flow is a better choice for container-based authentication when a browser isn't required. It eliminates the extra redirects used by this flow. If your clients can handle the redirects and you prefer to use this flow, you can set the idp.authn.RemoteUser.nonBrowserSupported property in authn/authn.properties.

Note that upgraded systems will have alternate, legacy approaches to configuring this feature, as noted above.