Page History
This appendix is designed to guide system admins installing Single-Sign-On (SSO) for Shrine (using Shibboleth).
Very Basic Overview of SSO
todo: For ajp, add prefix in shib2.xml, add permitted pattern in 8009 connector in server.xml
See: https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2067400159/JavaHowTo
See https://stackoverflow.com/questions/63505670/apache-cant-connect-to-new-tomcat-9-ajp
...
IdP (Identity Provider): A web-based system that can authenticate a user on behalf of another system called a SP (for Service Provider).
...
Among other things, The SP must be configured to specify which of these attributes should be passed to the shrine code (in the form of request attributes).
Installation Layout
The following instructions assume that (1) you are using Tomcat as your application server, and (2) Apache and Tomcat are running on the same host.
For our own local installation the following layout is used:
/opt/shrine/tomcat ← Tomcat home
/etc/shibboleth ← Shibboleth configuration files
/etc/httpd/* ← Apache configuration files
/var/www/html ← Apache static content as set in, for instance, /etc/httpd/conf/httpd.conf
Quick Instructions for Adjusting Configuration and Getting Going
The following instructions are meant to get you going as quickly as possible. If you want a better understanding of what's going on, go to the next section of this document.
Among the many configuration files, there are nine which need to be modified to reflect your installation, as follows:
...
/etc/shibboleth/idp-metadata.xml
...
/etc/shibboleth/sp-key.pem
/etc/shibboleth/sp-cert.pem
...
Create a key pair; include the content of the certificate (sp-cert.pem) in sp-metadata.xml, and the paths in the <CredentialResolver> element of shibboleth2.xml
...
/var/www/html/sp-metadata.xml
– if your Apache sets DocumentRoot to /var/www/html (for instance in /etc/httpd/conf/httpd.conf)
...
To be shared dynamically with your site's Shibboleth IdP (i.e. make it available at a given URL and share that URL with your IdP's maintainers/admins; or omit from the SP, and instead email it to the IdP admins
In either case, populate the public key certificate with yours
...
Tells Apache to require Shibboleth login for Shrine Urls (/shrine-api/*), and to proxy all the relevant requests to the Shrine application.
Tomcat should open port 8009 only to localhost, and should reside on the same host as your SP.
...
shrine.conf
override.conf
...
/opt/shrine/tomcat/lib/shrine.conf
/opt/shrine/tomcat/lib/override.conf
replace "shrine-sso-node01" with your own node name
add the following element under the top-level "shrine" element:
queryEntryPoint {
authenticationType = "sso"
}
OR add the following line to override.conf:
shrine.queryEntryPoint.authenticationType = "sso"
...
HTTP servlet request attributes and/or headers).
Shibboleth config Documentation
This is not required reading, but if you want to jump in depth, this is the official Shibboleth configuration documentation
Each of these files needs to be adjusted to the particulars of your site, your requirements.
You can search for the marker: 'ADJUST_FOR_YOUR_SITE' in those files for indications of what / where you need to edit.
More-Detailed Discussion of Shibboleth, Apache, and Tomcat Configuration
Here we discuss key items in the various configuration files; not necessarily the items that need to be modified but those that deserve an explanation.
Apache Configuration
Note: Apache version should be 2.4.10 or higher so that the local address request field gets populated for use in the back-end code. (see: https://bz.apache.org/bugzilla/show_bug.cgi?id=56661). If it isn't populated the back-end fails with an NPE when looking for the local address in the request.
/etc/httpd/conf.d/sp.conf
ServerName should be set to your SP host's name, for instance my-shibboleth-sp-host.net:
ServerName shrine-sso-node01.catalyst.harvard.edu
The following tells Apache to proxy all calls to a URL starting with "shrine-api" to http://127.0.0.1:8009/shrine-api/. Therefore we need to set up Tomcat to listen for HTTP traffic on port 8009 (see Tomcat Configuration below)
ProxyPass "/shrine-api/" "ajp://<YOUR_HOST>:8009/shrine-api/".
The following tells Apache to use Shibboleth for authentication for any URL starting with "shrine-api":
<LocationMatch "/shrine-api/">
AuthType shibboleth
ShibRequestSetting requireSession 1
Require valid-user local
The following tells Shibboleth to make the attributes it collects from the IdP available as request attributes in Apache. This is recommended over using the ShibUseHeaders
option. see https://shibboleth.atlassian.net/wiki/spaces/SHIB2/pages/2577072327/NativeSPApacheConfig.
ShibUseEnvironment On
ShibUseHeaders Off
</LocationMatch>
Shibboleth Configuration
Shibboleth consists of a Daemon plus an apache module. This Apache module must be configured for Shibboleth to intercept certain requests (see Apache Configuration above). When a request is intercepted, Shibboleth will decide whether the user (1) needs to login at the configured IdP (which will present a login form to the user), or (2) is already logged in (and Shibboleth will let the request be served as if it wasn't there to intercept it)
/etc/shibboleth/shibboleth2.xml
entityID: the ID of our Service Provider (SP)
REMOTE_USER: how the REMOTE_USER attribute will be populated, in the form of a list of attribute names. Note that "ecommonsid" which is specific to HMS IT, comes first, so for this environment REMOTE_USER will be set to the value of "ecommonsid". Otherwise, the first attribute name from the list which matches the name of an attribute returned by the IdP will be used. "attributePrefix" must be set to "AJP_" so that the attributes from the "attribute-map.xml
" file (see below) will be passed to Tomcat as request attributes (as opposed to request headers). See also server.xml on the same topic.
See: https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2067400159/JavaHowTo
See https://stackoverflow.com/questions/63505670/apache-cant-connect-to-new-tomcat-9-ajp
<ApplicationDefaults entityID="https://shrine-sso-node01.catalyst.harvard.edu"
REMOTE_USER="ecommonsid eppn uid persistent-id targeted-id"
signing="true"
attributePrefix="AJP_"
>
Sessions configuration documentation is available at https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/20653343422065335529/Sessions
TO DO: set checkAddress to "true" and test.
...
The following specifies the entityID of the IdP to use for authentication. We also specify that we speak only SAML2 protocol.
<SSO entityID="http://sso.med.harvard.edu/adfs/services/trust">
SAML2
</SSO>
When logging out, only log out of the local Shibboleth session.
<Logout>Local</Logout>
Setting the status-reporting-service URL (relative to the hostname) to "/Shibboleth.sso/Status"
<Handler type="Status" Location
="/Statu
s"/>
Setting the session diagnostic service to "/Shibboleth.sso/Session"
...
The IdP's metadata is stored in a file called idp-metadata.xml. It should be obtained from the IdP admin/maintainer.
<MetadataProvider type="XML" validate="true" path="idp-metadata.xml"/>
The attribute-map.xml file will specify which attributes are extracted from the IdP's response and the name of the request headers they will be available as (to the java code). More on this file later.
<AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
We left this and the file it points to unchanged:
<AttributeResolver type="Query" subjectMatch="true"/>
<AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
This points to the key pair we created above:
<CredentialResolver type="File" key="/etc/shibboleth/sp-key.pem" certificate="/etc/shibboleth/sp-cert.pem"/>
We left this and the files it points to unchanged:
...
If needed, refer to shibboleth2.xml.dist
File idp-metadata.xml
Get from your IdP (Probably do not (need to) distribute ours)
File attribute-map.xml
<Attributes xmlns="urn:mace:shibboleth:2.0:attribute-map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...
Developer tools
- SAML : "SAML DevTools extension" for Chrome. These tools let you view encoded SAML content.
A Decent Book on SAML
- Stefan Rasmusson: "SAML 2.0; Designing Secure Identity Federation". Just one of many books on the topic.
Next Step:
SHRINE 4.0.0 Appendix A.1 - Installing the Software Stack
Tomcat Configuration
Tomcat should accept requests on port 8080, but only from localhost, and redirect to the SSL port 6443:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
address="127.0.0.1"
redirectPort="6443" />
Configure port 6443:
<Connector port="6443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true">
<SSLHostConfig clientAuth="none" sslProtocol="TLS" sslEnabledProtocols="TLSv1.3,TLSv1.2"
honorCipherOrder="true" ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256">
<Certificate certificateKeystoreFile="/opt/shrine/shrine.keystore"
certificateKeystorePassword="changeit"
certificateKeyAlias="*.catalyst.harvard.edu" />
</SSLHostConfig>
</Connector>
Configure the AJP connector. Note the "allowedRequestAttributesPattern=".*"
attribute. That is needed for the AJP connection so that the attributes from the "attribute-map.xml
" file (see above) will be passed to the ServletRequest object as request attributes (as opposed to request headers). See also shibboleth2.xml on the same topic.
<Connector protocol="org.apache.coyote.ajp.AjpNio2Protocol"
proxyName="shrine-sso-node01"
enableLookups="true"
address="0.0.0.0"
allowedRequestAttributesPattern=".*"
port="8009"
secretRequired="false"
redirectPort="6443" />
File sp-metadata.xml
The entityId attribute specifies who we are
<!-- ADJUST_FOR_YOUR_SITE (EntityDescriptor-entityID) -->
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://shrine-sso-node01.catalyst.harvard.edu">
<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor>
<ds:KeyInfo>
<ds:X509Data>
<!-- ADJUST_FOR_YOUR_SITE (X509Certificate) →
The certificate contains the public key that was generated earlier
...
BAMTDDc5OTQzZmVlNzg2NTAeFw0xNTEyMTEwMzAwNDJaFw0yNTEyMDgwMzAwNDJa
MBcxFTATBgNVBAMTDDc5OTQzZmVlNzg2NTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALPBzAz0DTn+j2YsQKfqWI+m08lP5UzwVsE9ZKzLqO3PRHZqiOBm
EaFmRrYCZCAOcJ0TXcxPGtNSo8HC4uw5/Y5lJGuI3jN7X7KB1VUQDpUSwfgOqtro
uDoVRKrsaYZTnlNV8KbZ0WQz5s4Uw6CxKRB9RZ5iQMP1fuxc8B6GSOb3x69MiY6c
1jlgVAc6rV4zGfpafacxOLM8qcYhY8u3TiSd0H+oiGEqi1mFLK8yp6FKzX8OUkQf
We49YHz6wBxFOe+/p+7ziym1rBs/lGfenEo8ziCIMmjnoo257fz00bcz9rFl1rTx
KLFfgy72xTlG72l6u+pB9VqK3YNJS52Ns5UCAwEAAaM6MDgwFwYDVR0RBBAwDoIM
Nzk5NDNmZWU3ODY1MB0GA1UdDgQWBBRiDMNPjiAMC50WWubI3PMjP45S/DANBgkq
hkiG9w0BAQUFAAOCAQEAYZM/iWgC93vAq0d98egEzvESKodxHffkDOagd4Kxt/S0
AAHsVQCmAK/9kmRhsWzR3f1KIw98q4EX7nH/K68BFrerUvaL5+fEGE9W6Ki6QdW8
bM17GQkLyRDKZzGPm/hsaG1Oxru2kDf7qSvv59aRZlZ8skrDEnx8+dZ8JKC02ZDU
ClC+xWl1UPfO2BL4tJei/siSymGpiRqznQ2JMoTFu5CUUpoxyCVz1bl9lCVceoJ9
FaL38knS0p5DnXcm+I8wqNEVGLDPbDalBQryhJT9fIMm1/B85gB3AWAvcu9PPfHK
lQQUhxyEXTBJx3luLlpIjoloFKIute9K7pE5qAENjg== </ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<!-- ADJUST_FOR_YOUR_SITE (ssertionConsumerService-Location) -->
<!-- NB: Adjust the host, but keep the /Shibboleth.sso... -->
the "Location" attribute specifies the URL at which the IdP will post the user info after a successful login:
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://shrine-sso-node01.catalyst.harvard.edu/Shibboleth.sso/SAML2/POST" index="1"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
Developer tools
- SAML : "SAML DevTools extension" for Chrome
Appendix: a Decent Book
...