Deploy A Test SAML Identity Provider
If you are developing a web service, and you want to make it capable of integrating with a SAML SSO, then you are going to need to deploy a SAML identity provider to test against. Deploying a production-ready identity provider service is time consuming. Luckily, we don't need to do this.
This tutorial will help you deploy an example identity provider with the help of SimpleSAML and Docker.
Steps
Deploy a VM with docker-compose installed.
Create Apache Configuration
Unfortunately, we need to create an Apache configuration, so that we can tell the service about our custom SSL certificates.
editor apache.conf
<VirtualHost *:8080>
DocumentRoot /var/www/simplesamlphp
Alias /simplesaml /var/www/simplesamlphp/www
<Directory /var/www/simplesamlphp/www>
<IfModule !mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
</VirtualHost>
<VirtualHost *:8443>
DocumentRoot /var/www/simplesamlphp
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/site.crt
SSLCertificateKeyFile /etc/apache2/ssl/private.pem
SSLCertificateChainFile /etc/apache2/ssl/ca.crt
Alias /simplesaml /var/www/simplesamlphp/www
<Directory /var/www/simplesamlphp/www>
<IfModule !mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
</VirtualHost>
SSL certificates
Now create your SSL certificates in whatever manner works for you. I like to generate genuine certificates through Let's Encrypt with the help of AcmePHP, but you may wish to create your own self signed certificates.
Create a folder called ssl
and put the the certificates in there with the following names:
- site.crt - your site's public certificate.
- ca.crt - the public certificate of your certificate authority (e.g. Let's Encrypt).
- private.pem - your site's private certificate file.
SSLCertificateChainFile
line in the apache.conf
file.
Create Docker Compose File
Now we can put it all together. Create a docker-compose.yml
file with the following (swapping out idp.mydomain.com
with the FQDN you assing to the server).
editor docker-compose.yml
version: "3.9"
services:
saml:
image: kristophjunge/test-saml-idp
ports:
- 8080:8080
- 8443:8443
container_name: idp-server
volumes:
- type: bind
target: /etc/apache2/sites-enabled/simplesamlphp.conf
source: ./apache.conf
read_only: true
- type: bind
target: /etc/apache2/ssl
source: ./ssl
read_only: true
environment:
- SIMPLESAMLPHP_SP_ENTITY_ID=https://service-provider.mydomain.com
- SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE=https://service-provider.mydomain.com/auth/saml-login-handler
- SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE=https://service-provider.mydomain.com/auth/saml-logout-handler
8443
and 8080
are hardcoded in the codebase with redirects etc, so switching to ports 80 and 443 are too problematic.
Environment Variables
The SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE
and SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE
define the endpoints of your website that is acting as a service provider.
These endpoints should be handling the responses from the IDP for authentication and logging out respectively.
Deploy
Run docker-compose up
to spin up the service.
Testing
If you go to https://idp.mydomain.com:8443/simplesaml in your browser (swapping out idp.mydomain.com for your server's domain), then you should see the following screen showing you that the service is up.
Users
You can now start developing your service to act as a service provider against this identity provider. When doing so, be aware that there are two static users configured with the following data:
| UID | Username | Password | Group | Email |
| ----| -------- | ----------| ------ | ----------------- |
| 1 | user1 | user1pass | group1 | user1@example.com |
| 2 | user2 | user2pass | group2 | user2@example.com |
Admin User
If you need to login as the admin user, the password is: secret
.
Optional - Set Own Signing Certificates
The default deployment will use a public/private certificate pair that came with the image in order to perform the signing of the SAML requests. If you need to set these to your own, then first we need to generate our own certificate pair:
openssl req \
-newkey rsa:2048 \
-nodes -keyout server.pem \
-x509 \
-days 365 \
-out server.crt
Put these within a folder called signing-certs
.
Next, we need to mount them into the docker container through the use of a volume like so:
version: "3.9"
services:
saml:
image: kristophjunge/test-saml-idp
ports:
- 8080:8080
- 8443:8443
container_name: idp-server
volumes:
- type: bind
target: /etc/apache2/sites-enabled/simplesamlphp.conf
source: ./apache.conf
read_only: true
- type: bind
target: /etc/apache2/ssl
source: ./ssl
read_only: true
- type: bind
target: /var/www/simplesamlphp/cert
source: ./signing-certs
read_only: true
environment:
- SIMPLESAMLPHP_SP_ENTITY_ID=https://app.programster.org
- SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE=https://app.programster.org/auth/saml-login-handler
- SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE=https://app.programster.org/auth/saml-logout-handler
Now re-deploy the container for the changes to take effect.
docker-compose up
Finally, check that the certificates appear correctly on the page https://idp.mydomain.com:8443/simplesaml/saml2/idp/metadata.php?output=xhtml and that there isn't some kind of permission/access error that may need resolving. Don't forget that the filenames will need to be server.pem and server.crt.
Conclusion
You now have an test identity provider set up. You may wish to look at my example code on GitHub which demonstrates setting up a service provider in PHP-based site with the help of the programster/saml package.
References
First published: 14th August 2021