AutomatedIssuerGeneration

This software is not yet released and this is preliminary documentaton subject to significant change. It should not be used in production or to protect important resources at this stage.

AutomatedIssuerGeneration

This topic explains, with an example, a built-in way to generate the issuer value used when creating outbound messages and evaluating inbound messages in any protocol. In SAML, this refers to the entityID value used by the SP and in OIDC, this is the client_id value used by the RP.

Background

The older SP gained a feature later on in its lifecycle to automate the generation of SP entityIDs on the fly using a simple substitution that would plug in a request’s hostname to produce the entityID string. This was designed to help with large-scale virtual hosting so that the entityID would be automatically created in a standard format but varying based on host.

Of course, it was always possible, and arguably can often be a better option, to use a single entityID across many hosts, but there are times when this doesn’t make as much sense, particularly if different groups of people are operating the different sites for very different purposes.

With this release, the responsibility for assigning the outbound entityID to a request lies with the Hub and since this is Java and Spring, it becomes much simpler to generalize this solution because most of the Hub’s profile-related settings can be created dynamically using strategy functions or predicates (in Java, scripted, or other ways).

General Approach

In most cases, an Agent as a whole is to be assigned an issuer value. This is accomplished statically by setting the issuer property inside an Agent bean in the agents.xml file. A Java property can set a global value for this but a multiple-Agent Hub generally needs to set this explicitly when adding new Agents.

As with most settings of this sort, it is also possible to define a lookup function to return the value to use via the issuerLookupStrategy bean property. This same property also exists at lower layers of the configuration, notably when defining Application or RelyingParty overrides, but this is less common and usually unnecessary (in particular because the most common reasons for this are addressed by dynamically computing the value at the top level anyway, the exact subject of this page).

Thus the suggested approach to generate an entityID or client_id would be to define a bean of type Function<ProfileRequestContext,String> and reference it in an Agent bean like so:

<bean id="custom.IssuerStrategy" parent="shibboleth.ContextFunctions.Scripted" c:outputType="java.lang.String" p:hideExceptions="true"> <constructor-arg name="scriptSource"> <value> <![CDATA[ "https://sp.example.org" + "/sp" ]]> </value> </constructor-arg> </bean> <bean p:id="sp.example.org" parent="shibboleth.sp.Agent" p:issuerLookupStrategy-ref="custom.IssuerStrategy" />

Template Support

To make this as simple as possible, while retaining a lot of flexibility, a Java bean called shibboleth.sp.TemplatedLookupStrategy is supplied for you that can generate a String to use by evaluating a Velocity Template against a context containing information about the request to the Hub that you can use to generate the values, much like the Attribute Resolver can generate LDAP or SQL queries in a similar way.

This bean is not limited to generating an issuer string of course, it works anywhere a Function<ProfileRequestContext,String> bean is usable.

The variables defined to the Velocity engine are as follows:

Name

Type

Description

Name

Type

Description

profileRequestContext

ProfileRequestContext

Root of the context tree for the request from the Agent

agentRequestContext

AgentRequestContext

Subcontext containing key information about the request specific to the Agent/Hub protocol such as the requesting Agent, Application, and access to the remoted HTTP request and response from the Agent, if present

paramEscaper

Escaper

Guava implementation that URL-escapes data suitable for query string parameter inclusion

fragmentEscaper

Escaper

Guava implementation that URL-escapes data suitable for URL fragment inclusion

pathEscaper

Escaper

Guava implementation that URL-escapes data suitable for path inclusion

custom

any

A custom object injected by the deployer via the customObject bean property

The most common scenario (emulating the behavior of the older SP) is demonstrated below and involves using the “agentRequestContext” variable to poke down into the information representing the request to the Agent that is being processed, which contains, among other things, the hostname of that request. This is NOT the hostname of the Hub itself, of course.

Template Example

This example directly reproduces the older SP’s entityIDSelf hostname-replacement feature:

<bean id="custom.IssuerStrategy" parent="shibboleth.sp.TemplatedLookupStrategy" p:templateText="https://$agentRequestContext.getRemotedHttpServletRequest().getServerName()" /> <bean p:id="sp.example.org" parent="shibboleth.sp.Agent" p:issuerLookupStrategy-ref="custom.IssuerStrategy" />

The example assumes that the relevant objects are available to return a result, but in essentially every case where the issuer value would be needed and derived from the configuration, this is going to be true.