...
Code Block |
---|
(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
Localtabgroupexpand |
---|
Localtab live |
---|
|
Use conf/authn/external-authn-config.xml to configure this flow. The shibboleth.authn.External.externalAuthnPath bean defines the flow redirection path to the resource that's used to perform the external login, by default a context-relative location. It can be modified if needed, but must be a resource with access to the container session. Modify as needed to match the location of your external interface (see the documentation on flow redirects). Localtab live |
---|
| active | true
---|
Expand |
---|
|
Most of the usual options are available via authn/authn.properties, and some more advanced cases will require defining/adjusting bean definitions in authn/external-authn-config.xml. The idp.authn.External.externalAuthnPath property defines the flow redirection path to the resource that's used to perform the external login, by default a context-relative location. It can be modified if needed, but must be a resource with access to the container session. Modify as needed to match the location of your external interface (see the documentation on flow redirects). |
...
Call ExternalAuthentication.startExternalAuthentication(HttpServletRequest), saving off the result as a key.
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.
Set request attributes to communicate the result of the login back.
Call ExternalAuthentication.finishExternalAuthentication(String, HttpServletRequest, HttpServletResponse). The first parameter is the key returned in step 1.
A Example JSP implementation is below. It works as is, but is obviously quite limited.implementations are below.
Expand |
---|
title | External interface example in JSP |
---|
|
Code Block |
---|
| <%@ 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);
}
%> |
|
Expand |
---|
title | External interface with attributes in JSP |
---|
|
Code Block |
---|
| <%@ 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.
...
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
Localtabgroupexpand |
---|
Localtab live |
---|
|
The beans defined, or expected to be defined, in authn/external-authn-config.xml follow: Bean ID / Type | Default | Description |
---|
shibboleth.authn.External.externalAuthnPath String | contextRelative:external.jsp | Spring Web Flow redirection expression for the protected resource | shibboleth.authn.External.externalAuthnPathStrategy Function<ProfileRequestContext,String> | | Optional function that returns the redirection expression to use for the protected resource | shibboleth.authn.External.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.External.resultCachingPredicate Predicate<ProfileRequestContext> | | Optional bean that can be defined to control whether to preserve the authentication result in an IdP session | shibboleth.authn.External.addDefaultPrincipals Boolean | true | Whether to add the content of the supportedPrincipals property of the underlying flow descriptor to the resulting Subject | shibboleth.authn.External.matchExpression Pattern | | Regular expression to match username against |
localtab-live |
Expand |
---|
|
The beans defined, or expected to be defined, in authn/external-authn-config.xml follow: Bean ID / Type | Default | Description |
---|
shibboleth.authn.External.externalAuthnPathStrategy Function<ProfileRequestContext,String> | | Optional function that returns the redirection expression to use for the protected resource | shibboleth.authn.External.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.External.resultCachingPredicate Predicate<ProfileRequestContext> | | Optional bean that can be defined to control whether to preserve the authentication result in an IdP session |
Localtab live |
---|
| active | true
---|
Expand |
---|
|
The flow-specific properties usable via authn/authn.properties are: Name | Default | Description |
---|
idp.authn.External.externalAuthnPath | contextRelative:external.jsp | Spring Web Flow redirection expression for the protected resource | idp.authn.External.matchExpression | | Regular expression to match username against |
The general properties configuring this flow via authn/authn.properties are: Name | Default | Description |
---|
idp.authn.External.order | 1000 | Flow priority relative to other enabled login flows (lower is "higher" in priority) | idp.authn.External.nonBrowserSupported | false | Whether the flow should handle non-browser request profiles (e.g., ECP) | idp.authn.External.passiveAuthenticationSupported | false | Whether the flow allows for passive authentication | idp.authn.External.forcedAuthenticationSupported | false | Whether the flow supports forced authentication | idp.authn.External.proxyRestrictionsEnforced | %{idp.authn.enforceProxyRestrictions:true} | Whether the flow enforces upstream IdP-imposed restrictions on proxying | idp.authn.External.proxyScopingEnforced | false | Whether the flow considers itself to be proxying, and therefore enforces SP-signaled restrictions on proxying | idp.authn.External.discoveryRequired | false | Whether to invoke IdP-discovery prior to running flow | idp.authn.External.lifetime | %{idp.authn.defaultLifetime:PT1H} | Lifetime of results produced by this flow | idp.authn.External.inactivityTimeout | %{idp.authn.defaultTimeout:PT30M} | Inactivity timeout of results produced by this flow | idp.authn.External.reuseCondition | shibboleth.Conditions.TRUE | Bean ID of Predicate<ProfileRequestContext> controlling result reuse for SSO | idp.authn.External.activationCondition | shibboleth.Conditions.TRUE | Bean ID of Predicate<ProfileRequestContext> determining whether flow is usable for request | idp.authn.External.subjectDecorator |
| Bean ID of BiConsumer<ProfileRequestContext,Subject> for subject customization | idp.authn.External.supportedPrincipals | (see below) | Comma-delimited list of protocol-specific Principal strings associated with flow | idp.authn.External.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: Code Block |
---|
| <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): Code Block |
---|
idp.authn.External.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 | localtab-live |
Expand |
---|
title | Flow Descriptor XML (V4.1+) |
---|
|
To replace the internally defined flow descriptor bean, the following XML is required: Code Block |
---|
| <util:list id="shibboleth.AvailableAuthenticationFlows">
<bean p:id="authn/External" parent="shibboleth.AuthenticationFlow"
p:order="%{idp.authn.External.order:1000}"
p:nonBrowserSupported="%{idp.authn.External.nonBrowserSupported:false}"
p:passiveAuthenticationSupported="%{idp.authn.External.passiveAuthenticationSupported:false}"
p:forcedAuthenticationSupported="%{idp.authn.External.forcedAuthenticationSupported:false}"
p:proxyRestrictionsEnforced="%{idp.authn.External.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}"
p:proxyScopingEnforced="%{idp.authn.External.proxyScopingEnforced:false}"
p:discoveryRequired="%{idp.authn.External.discoveryRequired:false}"
p:lifetime="%{idp.authn.External.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
p:inactivityTimeout="%{idp.authn.External.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
p:reuseCondition-ref="#{'%{idp.authn.External.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
p:activationCondition-ref="#{'%{idp.authn.External.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
p:subjectDecorator-ref="#{getObject('%{idp.authn.External.subjectDecorator:}'.trim())}">
<property name="supportedPrincipalsByString">
<bean parent="shibboleth.CommaDelimStringArray"
c:_0="#{'%{idp.authn.External.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. |
...