Versions Compared

Key

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

...

Finally, for non-browser use, it's also possible to supply the code in a request header, "X-Shibboleth-TOTP" by default, also controllable with a property. Because of this, the flow is installed by default as supporting non-browser use, though if the header is missing there is no user interface to ask for one.

Source of Token Seeds

This plugin supports a public interface to obtain the token seeds for a specific user at runtime. There are two implementations provided, as described below.

Expand
titleUsing the Attribute Resolver

The default behavior of the flow is to perform a special attribute resolution step to resolve an attribute named by the idp.authn.TOTP.tokenSeedAttribute property, defaulting to "tokenSeeds". Since the attribute name really shouldn't matter much, leaving it defaulted is usually the best choice but if you want to set the property you can put it in any of the existing property files, advisedly the conf/authn/authn.properties file added in V4.1.

The attribute itself must supply one or more string values containing the Base32-encoded token seed(s) to try and validate the supplied code against. Note these seeds cannot be encrypted at this stage. If you wish to store them in an encrypted form, it's possible to do so using the IdP using its "DataSealer" component that manages a list of keys shared amongst all the nodes of a cluster. Assuming this is done (details below), the DecryptedAttributeDefinition can be used to decrypt them on the fly to produce the resulting attribute.

DataSealer Definition and Use

While most IdPs include a DataSealer configured internally, this is typically not a good choice for this use case because the original use cases tend to assume the keys are being rotated frequently. To use a longer-term key, a dedicated component will typically be required. In order to facilitate using it to encrypt data using the command line, it's a good idea to define it in a separate Spring resource and load that into the Attribute Resolver's set of configuration resources in conf/services.xml.

Note that you will need to use the seckeygen utility yourself out of band to initialize the keystore and a key to use:

Initializing keystore
Code Block
languagebash
$ cd /opt/shibboleth-idp
$ bin/seckeygen.sh --alias totp --count 1 \
	--storefile credentials/totpsealer.jks \
    --storepass password \
    --versionfile credentials/totpsealer.kver
Dedicated DataSealer configuration
Code Block
languagexml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"

       default-init-method="initialize"
       default-destroy-method="destroy">

    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
        p:placeholderPrefix="%{" p:placeholderSuffix="}" />

    <bean id="totp.DataSealerKeyStrategy" lazy-init="true"
            class="net.shibboleth.utilities.java.support.security.impl.BasicKeystoreKeyStrategy"
        p:keystoreType="JCEKS"
        p:keystoreResource="%{idp.home}/credentials/totpsealer.jks"
        p:keyVersionResource="%{idp.home}/credentials/totpsealer.kver"
        p:keyAlias="totp"
        p:keystorePassword="password"
        p:keyPassword="password"
        p:updateInterval="PT1H" />

    <bean id="totp.DataSealer" lazy-init="true"
        class="net.shibboleth.utilities.java.support.security.DataSealer"
        p:keyStrategy-ref="totp.DataSealerKeyStrategy" />

 </beans>

With this example, a DecryptedAttributeDefinition's dataSealerRef property would be set to "totp.DataSealer".

To use this from the command line to encrypt (and for example purposes, decrypt) data, assuming the file were named conf/totpsealer.xml:

DataSealer Command Example
Code Block
languagebash
$ cd /opt/shibboleth-idp
$ bin/sealer.sh --quiet conf/totpsealer.xml dec `bin/sealer.sh --quiet conf/totpsealer.xml enc data`
data
Tip

Note that the data produced by encryption is generally (though not absolutely required to be) Base64-encoded. This is not the same as how the token seed itself may be encoded, as the seed is in cleartext. The typical encoding for an encrypted seed would be a Base32-encoded seed, encrypted and encoded with Base64.

...