The Shibboleth IdP V4 software will leave support on September 1, 2024.

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 24 Next »

Current File(s): conf/authn/external-authn-config.xml, conf/authn/authn.properties (V4.1+)
Format: Native Spring, Properties (V4.1+)

Overview

The authn/External login flow supports the use of an arbitrary external (to the IdP) authentication mechanism. Its basic function is to provide a non-WebFlow-based integration strategy for new authentication mechanisms. As a rule, using WebFlow is better and safer, but it does require writing Java code in most cases. This is usually true for external mechanisms also, but they can in some cases be implemented with JSP alone.

By default, the External flow is defined to lack support for advanced controls such as passive or forced authentication, but this can be changed if your integration supports these features.

This login handler usually requires additional code be written in order to trigger the external authentication system. If you're simply looking to authenticate based on the presence of REMOTE_USER, refer to the RemoteUser flow.

Once control is transferred to the external path, the IdP has no control over what happens, and it will implicitly trust any information passed back through the defined interface. If that information can be manipulated, security holes may result. The deployer takes full responsibility for the security of the overall exchange.

Enabling Module (V4.1+)

For V4.1+, configuring and using this feature requires that you first enable the "idp.authn.External" 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.

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

General Configuration

You may also dynamically derive the path to use, typically so that it can vary based on aspects of the request, by defining a bean named shibboleth.authn.External.externalAuthnPathStrategy of type Function<ProfileRequestContext,String>.

The shibboleth.authn.External.ClassifiedMessageMap is a map of exception/error messages to classified error conditions. You can make use of this map either by modifying it to understand the error or exception messages returned by your external code, or by using the map as is and passing back the literal tokens in the map from your external code via the exception or error message interface.

API

The ExternalAuthentication class makes up the interface between the external code and the IdP. The general flow is:

  1. Call ExternalAuthentication.startExternalAuthentication(HttpServletRequest), saving off the result as a key.

  2. Do work as necessary (reading request details from the attributes below). Any redirects must preserve the key value returned in step 1 because it must be used to complete the login later.

  3. Set request attributes to communicate the result of the login back.

  4. Call ExternalAuthentication.finishExternalAuthentication(String, HttpServletRequest, HttpServletResponse). The first parameter is the key returned in step 1.

A JSP implementation is below. It works as is, but is obviously quite limited.

External interface example in JSP
<%@ page pageEncoding="UTF-8" %>
<%@ page import="net.shibboleth.idp.authn.ExternalAuthentication" %>
<%@ page import="net.shibboleth.idp.authn.ExternalAuthenticationException" %>

<%
try {
    final String key = ExternalAuthentication.startExternalAuthentication(request);
    final String username = request.getRemoteUser();
    if (username != null) {
        request.setAttribute(ExternalAuthentication.PRINCIPAL_NAME_KEY, username);
    }
    ExternalAuthentication.finishExternalAuthentication(key, request, response);
     
} catch (final ExternalAuthenticationException e) {
    throw new ServletException("Error processing external authentication request", e);
}
%>
External interface with attributes in JSP
<%@ page pageEncoding="UTF-8" %>
<%@ page import="net.shibboleth.idp.authn.*" %>
<%@ page import="net.shibboleth.idp.attribute.*"%>
<%@ page import="net.shibboleth.idp.authn.principal.*"%>
<%@ page import="java.util.*"%>

<%
try {
    final String key = ExternalAuthentication.startExternalAuthentication(request);

    HashSet<Principal> principals=new HashSet<Principal>();

    principals.add(new UsernamePrincipal("bbarker"));

    //<DataConnector xsi:type="Subject" exportAttributes="mail eduPersonNickname" id="myId" />
    //<AttributeDefinition ... <InputDataConnector ref="myId" ...
    IdPAttribute attr=new IdPAttribute("eduPersonNickname");
    attr.setValues(Collections.singleton(new StringAttributeValue("Bob Barker")));
    principals.add(new IdPAttributePrincipal(attr));

    attr=new IdPAttribute("mail");
    attr.setValues(Collections.singleton(new StringAttributeValue("bbarker@example.org")));
    principals.add(new IdPAttributePrincipal(attr));

    request.setAttribute(ExternalAuthentication.SUBJECT_KEY,new Subject(false, principals, Collections.EMPTY_SET, Collections.EMPTY_SET));

    ExternalAuthentication.finishExternalAuthentication(key, request, response);

} catch (final ExternalAuthenticationException e) {
    throw new ServletException("Error processing external authentication request", e);
}
%>

Inputs

On first access to the external resource, the request attributes below will be set.

Name

Type

Function

opensamlProfileRequestContext

ProfileRequestContext

Access to full request context tree

forceAuthn

Boolean

Whether the requester asked for re-authentication

isPassive

Boolean

Whether the requested asked for passive authentication

relyingParty

String

Name of the relying party requesting authentication

extended

Boolean

Whether this login flow has been invoked as an extension of another login flow

Outputs

Name

Type

Function

principalName          

String

Name of authenticated subject to use as the login result

principal

Principal

Java Principal object to use as the login result

subject

Subject

Java Subject object to use as the login result

authnError

String

Error message to return in place of a successful login

authnException

Exception

Explicit exception object to return in place of a successful login

authnInstant

Instant

Exact time of authentication to report back

authnAuthorities

Collection<String>

Ordered collection of URIs identifying upstream/proxied authenticating "authorities" used to authenticate the subject

attributes

Collection<IdPAttribute>

Collection of IdPAttribute objects to associate with the authenticated subject

doNotCache

Boolean

If true, prevents the result from being saved for future use for SSO

previousResult

Boolean

If true, the "new" AuthenticationResult is created with the "previousResult" flag set to true (mainly impacts auditing)

Only one "result" or error attribute should be set by the external code. Setting more than one has unspecified behavior. In most cases, the simple principalName should be returned on success, but you can return the more complex objects to pass back additional information such as public or private credentials or custom principal data.

Any IdPAttribute objects supplied will be processed by the AttributeFilter service as "inbound" data. If at least one value in the "authnAuthorities" attribute is supplied, it is set as the "issuer" of the attributes for the purposes of the filter evaluation.

Note that returning a Subject is often paired with setting the shibboleth.authn.External.addDefaultPrincipals bean (V4.0) or idp.authn.External.addDefaultPrincipals property (V4.1+) to false, to dynamically establish Principal(s) representing the authentication method used without having them overwritten. For example, your External flow's supportedPrincipals property might be defined to include both password and multi-factor authentication Principals (meaning it supports both methods), but you can return the specific method used at runtime in the Subject.

Reference

  • No labels