Skip to content

Installing from archive

Henri Mikkonen edited this page Mar 11, 2020 · 58 revisions

In this topic we install OIDC extension archive on top of existing

  • Shibboleth IdP 3.4+ installation for V1.x
  • Shibboleth IdP 4.x installation for V2.x

We will also make the necessary initial configurations for you to board your first relying party.

Install the archive

Archive contains the necessary binaries, flows, views and configurations. The archives can be found from:

By first extracting the archive and then rebuilding the Shibboleth IdP package necessary jars will be included to Shibboleth IdP. Please note that you do need to change the default ownership of the extracted files to match your existing Shibboleth IdP installation.

cd /opt/shibboleth-idp
tar -xf path/to/idp-oidc-extension-distribution-X.Y.Z-bin.tar.gz --strip-components=1
bin/build.sh

Import OIDC extension configuration files

The extension configuration files need to be imported to your Shibboleth IdP. The instructions show which files you need to import. You may also take alternative approach of just copying the beans.

Import global-oidc.xml to global.xml

edit /opt/shibboleth-idp/conf/global.xml

Add following to global.xml:

<!-- OIDC extension global bean definitions -->
<import resource="global-oidc.xml" />

Import credentials-oidc.xml to credentials.xml

edit /opt/shibboleth-idp/conf/credentials.xml

Add following to credentials.xml:

<!-- OIDC extension default credential definitions -->
<import resource="credentials-oidc.xml" />

Import services-oidc.xml to services.xml

edit /opt/shibboleth-idp/conf/services.xml

Add following to services.xml:

<!-- OIDC extension services definitions -->
<import resource="services-oidc.xml" />

Import oidc-relying-party.xml to relying-party.xml

edit /opt/shibboleth-idp/conf/relying-party.xml

Add following to relying-party.xml:

<!-- OIDC extension relying party definitions -->
<import resource="oidc-relying-party.xml" />

Add oidc-subject.properties and idp-oidc.properties as additional properties in idp.properties

edit /opt/shibboleth-idp/conf/idp.properties

Modify idp.additionalProperties to include oidc-subject.properties and idp-oidc.properties:

idp.additionalProperties=/conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties,/conf/authn/duo.properties, /conf/oidc-subject.properties, /conf/idp-oidc.properties

For V2.X: make sure that you have the idp.service.attribute.registry.namingRegistry set to OIDCExtendedNamingRegistry (i.e. idp.service.attribute.registry.namingRegistry=OIDCExtendedNamingRegistry)

Replace authn-comparison.xml with authn-comparison-oidc.xml

If you have not modified authn-comparison-oidc.xml yourself you may replace it with the provided authn-comparison.xml, otherwise you need to merge.

cp /opt/shibboleth-idp/conf/authn/authn-comparison-oidc.xml /opt/shibboleth-idp/conf/authn/authn-comparison.xml

Generate and set default keys

The default configuration expects to have two RSA keys and one EC key. They are expected to be in the JWK format, location defined with the following properties:

  • idp.signing.oidc.rs.key - Default: %{idp.home}/credentials/idp-signing-rs.jwk
  • idp.signing.oidc.es.key - Detault: %{idp.home}/credentials/idp-signing-es.jwk
  • idp.signing.oidc.rsa.enc.key - Default: %{idp.home}/credentials/idp-encryption-rsa.jwk

The keys need to be generated by you. One way to do this is via json-web-key-generator. Download the latest version from the release page (tested with v0.7) and compile it as instructed (you need Java JDK and Apache Maven for this). The result jar file can be used for generating the keys:

java -jar target/json-web-key-generator-0.7-jar-with-dependencies.jar -t RSA -s 2048 -u sig -i defaultRSASign -p > /opt/shibboleth-idp/credentials/idp-signing-rs.jwk
java -jar target/json-web-key-generator-0.7-jar-with-dependencies.jar -t EC -c P-256 -u sig -i defaultECSign -p > /opt/shibboleth-idp/credentials/idp-signing-es.jwk
java -jar target/json-web-key-generator-0.7-jar-with-dependencies.jar -t RSA -s 2048 -u enc -i defaultRSAEnc -p > /opt/shibboleth-idp/credentials/idp-encryption-rsa.jwk

Edit the generated keys by removing everything else than the section named as "Full key". For instance idp-signing-rs.jwk,

edit /opt/shibboleth-idp/credentials/idp-signing-rs.jwk

should look like:

{
"kty": "RSA",
"d": "gv7aqFcXV86j... ...l2j013JeSgQ",
"e": "AQAB",
"use": "sig",
"kid": "defaultRSASign",
"n": "pNf03ghVzMAw5sW.. ...RcslgXPqb6VOTJBVw"
}

Repeat the process for all three keys.

Restart

Now you should be able to restart Shibboleth IdP without any errors. If there are errors, please revisit earlier phases of installation.

Issuer, keyset and openid configuration

Now we have still few tasks to do. We need to set the openid connect issuer value and publish openid configuration.

Set your issuer value to idp-oidc.properties

# Set the Open ID Connect Issuer value
idp.oidc.issuer = https://your.issuer.example.com

The value must be URL using the https scheme that contains scheme, host, and optionally, port number and path components and no query or fragment components. And it must resolve to the deployment in question.

Common way for relying parties to initialize themselves for the provider is to read openid-configuration as defined in https://openid.net/specs/openid-connect-discovery-1_0.html. Template for the file is located in

/opt/shibboleth-idp/static/.well-known/openid-configuration

You should update it to match your configuration. At minimum this means replacing {{ service_name }} with host part your issuer. For relying party to locate the file you must configure your container to publish it in location:

https://your.issuer.example.com/.well-known/openid-configuration   

Now you are ready to onboard your first relying party.

Prepare for first relying party

Profile Configurations

We need to enable profile configurations for authorization and token endpoints (OIDC.SSO), userinfo endpoint (OIDC.UserInfo), token revocation (OAUTH2.Revocation) and keyset (OIDC.Keyset). Add also p:responderIdLookupStrategy-ref="profileResponderIdLookupFunction" that enables OIDC profiles to use issuer id instead of entity id as responder.

edit /opt/shibboleth-idp/conf/relying-party.xml

<bean id="shibboleth.UnverifiedRelyingParty"  p:responderIdLookupStrategy-ref="profileResponderIdLookupFunction" parent="RelyingParty">
    <property name="profileConfigurations">
        <list>
        <bean parent="OIDC.Keyset" />
        </list>
    </property>
</bean>  

<bean id="shibboleth.DefaultRelyingParty" p:responderIdLookupStrategy-ref="profileResponderIdLookupFunction"   parent="RelyingParty">
    <property name="profileConfigurations">
        <list>
            <bean parent="Shibboleth.SSO" p:postAuthenticationFlows="attribute-release" />
            <ref bean="SAML1.AttributeQuery" />
            <ref bean="SAML1.ArtifactResolution" />
            <bean parent="SAML2.SSO" p:postAuthenticationFlows="attribute-release" />
            <ref bean="SAML2.ECP" />
            <ref bean="SAML2.Logout" />
            <ref bean="SAML2.AttributeQuery" />
            <ref bean="SAML2.ArtifactResolution" />
            <ref bean="Liberty.SSOS" />
            <bean parent="OIDC.SSO" p:postAuthenticationFlows="attribute-release" />
            <bean parent="OIDC.UserInfo"/>
            <bean parent="OAUTH2.Revocation"/>
        </list>
    </property>
</bean>

Prepare filters and resolvers to release sub claim.

There are two example files on how to resolve and filter attributes, attribute.resolver-oidc.xml and attribute-filter-oidc.xml. At minimum you need to apply sub claim attribute resolving and resolve it for the clients.

Add subject resolution and data connector for it. Notice the new namespace definition you will have to include.

edit /opt/shibboleth-idp/conf/attribute-resolver.xml

<AttributeResolver xmlns="urn:mace:shibboleth:2.0:resolver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oidcext="org.geant.idpextension.oidc.attribute.encoder"
xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd org.geant.idpextension.oidc.attribute.encoder classpath:/schema/idp-oidc-extension-attribute-encoder.xsd">
<!-- ========================================== -->
<!-- Attribute Definitions -->
<!-- ========================================== -->


<!-- Subject Identifier is a attribute that must always be resolved.
There has to be exactly one resolved and filtered attribute that would be encoded as 'sub'.
This example attribute (the data connector actually ) will generate public or pairwise 'sub' depending on client registration data.  -->

<AttributeDefinition id="subject" xsi:type="Simple" activationConditionRef="SubjectRequired">
    <InputDataConnector ref="computedSubjectId" attributeNames="subjectId"/>
    <AttributeEncoder xsi:type="oidcext:OIDCString" name="sub" />
</AttributeDefinition>

<!-- ========================================== -->
<!-- Data Connectors -->
<!-- ========================================== -->

<!-- Data Connector for generating 'sub' claim.
     The connector may be used to generate both public and pairwise subject values -->
<DataConnector id="computedSubjectId" xsi:type="ComputedId"
        generatedAttributeID="subjectId"
        salt="%{idp.oidc.subject.salt}"
        algorithm="%{idp.oidc.subject.algorithm:SHA}"
        encoding="%{idp.oidc.subject.encoding:BASE32}">
        <InputAttributeDefinition ref="%{idp.oidc.subject.sourceAttribute}"/>
</DataConnector>   

Add now a filtering rule that releases the claim to all openid connect relying parties. Notice the new namespace definition you will have to include.

edit /opt/shibboleth-idp/conf/attribute-filter.xml 

<AttributeFilterPolicyGroup id="ShibbolethFilterPolicy" xmlns="urn:mace:shibboleth:2.0:afp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oidcext="org.geant.idpextension.oidc.attribute.filter"
xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd org.geant.idpextension.oidc.attribute.filter classpath:/schema/idp-oidc-extension-afp.xsd">


<AttributeFilterPolicy id="OPENID_SCOPE">
    <PolicyRequirementRule xsi:type="oidcext:OIDCScope" value="openid" />
    <AttributeRule attributeID="subject">
        <PermitValueRule xsi:type="ANY" />
    </AttributeRule>
</AttributeFilterPolicy> 

Add an RP as a trusted client example - Just to test that installation works

Add a file metadaresolver by enabling the commented out example from oidc-metadata-providers.xml

edit /opt/shibboleth-idp/conf/oidc-metadata-providers.xml

<util:list id="shibboleth.oidc.ClientInformationResolvers"
    value-type="org.geant.idpextension.oidc.metadata.resolver.ClientInformationResolver">
    <ref bean="ExampleFileResolver" />
    <ref bean="ExampleStorageClientInformationResolver" />
</util:list>

<bean id="ExampleFileResolver"
    class="org.geant.idpextension.oidc.metadata.impl.FilesystemClientInformationResolver"
    p:id="ExampleFileResolver1"
    p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" c:metadata="/opt/shibboleth-idp/metadata/oidc-client.json">
</bean>

Add finally the client registration data

edit /opt/shibboleth-idp/metadata/oidc-client.json

[
  {
    "scope":"openid phone",
    "redirect_uris":["https://demorp.example.com/redirect_uri"],
    "client_id":"demo_rp",
    "client_secret":"topsecret",
    "response_types":["code"],
    "grant_types":["authorization_code"]
  }
]

You will have to of course set the data to match the client you are using. Wiki should be of some help with this. The example data belongs to a client with single redirect uri to perform code flow and having possibility to request for scope 'phone'.

Restart

You should now be able to authenticate with the client. Happy configuring!

Clone this wiki locally