SAML Quick Start on Azure
This Quick Start Guide will guide you through setting up a sandbox HAProxy Enterprise SAML Component implementation in a Ubuntu 20.04 LTS local virtual machine
We will enable single sign-on to a local NGINX instance. We will use Azure Active Directory as the Identity Provider. HAProxy Enterprise SAML Component will be the Service Provider.
Conventions
The procedures below use the following icons:
-
Perform the step in Microsoft Azure.
-
Perform the step in a Bash terminal.
-
Perform the step in a browser.
Create a sample local application
Create a new Ubuntu Desktop 20.04 LTS local virtual machine.
Log in to your new local virtual machine.
The procedures below will all take place on the local virtual machine.
We will set up an NGINX instance on the local virtual machine as a sample application. It will listen on localhost on port 3200 and will not be SAML-enabled on its own.
Launch a terminal.
-
Install NGINX:
$ sudo apt install nginx -y
-
Make the NGINX instance listen on port 3200:
$ sudo sed -i 's/80/3200/' /etc/nginx/sites-enabled/default $ sudo systemctl restart nginx
-
Connect to
127.0.0.1:3200
via a web browser.The NGINX instance's welcome page displays.
You cannot access it via
127.0.0.1:80
. We will give access to the sample local application on port 80 later on via HAProxy Enterprise SAML Component.
Create an Azure Active Directory enterprise application
Launch a web browser, then sign in to the Microsoft Azure portal as a cloud application administrator, or as an application administrator for your Azure Active Directory tenant.
In Microsoft Azure, create a new non-gallery enterprise application in Azure Active Directory.
-
Add the following variables to your
.bashrc
file:$ echo 'myazureapp="<Your Azure application name>"' >> ~/.bashrc $ echo 'idp_app_id="<Your Azure application ID>"' >> ~/.bashrc
We will use these variables later on to configure HAProxy Enterprise and HAProxy Enterprise SAML Component.
Click Assign users and groups, and grant access to the Azure Active Directory enterprise application to one or several users.
See also
Add an unlisted (non-gallery) application to your Azure AD organization
Set up the SAML parameters
-
Add a variable for your sample local application's FQDN to your
.bashrc
file:$ echo 'myappfqdn="<Your sample local application FQDN>"' >> ~/.bashrc
$ echo 'myappfqdn="app.example.local"' >> ~/.bashrc
-
Select Sign-on, then click SAML.
The Set up Single Sign-On with SAML page appears.
-
Edit the Basic SAML Configuration:
- Identifier (Entity ID)
-
Enter a SAML ID for your application. For the sake of simplicity, enter your Azure Active Directory enterprise application's name, which corresponds to the value of the
$myazureapp
variable.
samlappjuly1
- Reply URL (Assertion Consumer Service URL)
-
Enter
https://<Your sample local application's FQDN>/saml/reply
.https://app.example.local/saml/reply
- Logout Url
-
Enter
https://<Your sample local application's FQDN>/saml/logout
.https://app.example.local/saml/logout
Export the certificate and the tenant ID
Click the pencil in the SAML Signing Certificate area, then select Sign SAML response and assertion in the Signing option drop-down.
-
Download the Azure Openssl PEM format Base64 Azure Active Directory enterprise application' certificate.
For instance
samlappjuly1.cer
. Navigate to Azure Active Directory, then copy your tenant ID.
-
Add a variable for your tenant ID to your
.bashrc
file:$ echo 'idp_tenant_id="<Your Azure Active Directory tenant ID>"' >> ~/.bashrc
Install HAProxy Enterprise with SAML components
-
Add the following variables to your
.bashrc
file:$ echo 'hapeekey="<HAProxy Enterprise Key>"' >> ~/.bashrc $ echo 'hapeeversion="<HAProxy Enterprise version>"' >> ~/.bashrc $ echo 'samlapp="<Internal name for your sample local application>"' >> ~/.bashrc
Variable
Value
Example
hapeekey
HAProxy Enterprise key you received when you registered.
xxxxxxxx-xxxxxxxx
hapeeversion
HAProxy Enterprise version number.
2.1
samlapp
Application configured in the HAProxy Enterprise SAML Component
saml.ini
initialization fileYou can create several sections. Each section corresponds to an application.
MySAMLApp
-
Reload your
.bashrc
file to take into account the variables you've created:$ . .bashrc
-
Install cURL, OpenSSL, HAProxy Enterprise, and HAProxy Enterprise SAML Component:
This step uses the following variable:
$hapeekey
-
HAProxy Enterprise key you received when you registered.
$ sudo apt install curl openssl -y
$ curl -s https://www.haproxy.com/static/install_haproxy_enterprise.sh | sudo bash /dev/stdin 1.9r1 $hapeekey
$ sudo apt install hapee-extras-spoa-saml -y
Manage the HAProxy Enterprise SAML Component and Microsoft Azure certificates
-
Create a self-signed SSL certificate to allow connecting via HTTPS, then copy the certificate and the key to the right directory, with the right ownership:
This step uses the following variables:
$hapeeversion
-
HAProxy Enterprise version used in paths
$myappfqdn
-
Your sample local application's FQDN, used in the certificate Common Name.
The certificate is valid only if the request hostname matches the common name.
$ sudo openssl req -keyout key.pem -out cert.pem -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj "/C=FR/ST=IdF/L=Paris/O=HAProxy Technologies/OU=IT/CN=$myappfqdn" $ sudo cat key.pem cert.pem | sudo tee -a /etc/hapee-$hapeeversion/certs/mycert.pem $ sudo cp key.pem /etc/hapee-extras/ $ sudo chmod 744 /etc/hapee-extras/key.pem
-
Copy your Azure Active Directory enterprise application certificate to
/etc/hapee-extras/
, then make the current user the owner of the certificate:$ sudo cp ~/Download/$myazureapp.cer /etc/hapee-extras/ $ sudo chmod 744 /etc/hapee-extras/$myazureapp.cer
Configure HAProxy Enterprise and the HAProxy Enterprise SAML Component
The HAProxy Enterprise hapee-lb.cfg
configuration file will contain:
A SAML frontend to redirect user requests to HAProxy Enterprise SAML Component
-
The three following backends:
A backend for the Stream Processing Offload Engine
A default backend to manage errors
A backend for your sample local application
The following variable values will be implemented in the file:
$hapeeversion
-
HAProxy Enterprise version
$myappfqdn
-
Your sample local application's FQDN
$samlapp
-
Application configured in the HAProxy Enterprise SAML Component
saml.ini
initialization file
Create the HAProxy Enterprise
hapee-lb.cfg
configuration file:
$ cat <<EOF | sudo tee /etc/hapee-$hapeeversion/hapee-lb.cfg
global
crt-base /etc/hapee-$hapeeversion/certs
frontend ft-saml
bind :80
bind :443 ssl crt mycert.pem
mode http
option http-buffer-request
tcp-request inspect-delay 10s
timeout client 1m
http-request set-var(sess.saml_app) str($samlapp) if { hdr(host) -i $myappfqdn }
filter spoe engine spoe-saml config /etc/hapee-extras/hapee-saml-spoe.cfg
http-request send-spoe-group spoe-saml spoe-group-req
http-request redirect location %[var(txn.saml.redirect_to)] code 302 if { var(txn.saml.redirect_to) -m found }
http-request deny if ! { var(txn.saml.saml_auth_ok) -m bool } ! { var(txn.saml.saml_logout_ok) -m bool }
http-request set-header givenname %[var(txn.saml.givenname)]
http-request set-header display_name %[var(txn.saml.display_name)]
http-request set-header all_attributes_names %[var(txn.saml.all_attributes_names)]
http-request set-header all_attributes_values %[var(txn.saml.all_attributes_values)]
http-request set-header AuthnInstant %[var(txn.saml.AuthnInstant)]
http-request set-header AuthnInstant_ts %[var(txn.saml.AuthnInstant_ts)]
http-response set-header Set-Cookie %[var(txn.saml.set_cookie)] if { var(txn.saml.set_cookie) -m found }
http-response set-header saml-auth-error-text %[var(txn.saml.saml_auth_error_text)] if { var(txn.saml.saml_auth_error_text) -m found }
http-response set-header location %[var(txn.saml.redirect_after_auth)] if { var(txn.saml.redirect_after_auth) -m found }
http-response set-status 303 if { var(txn.saml.redirect_after_auth) -m found }
default_backend bk-err
use_backend %[var(txn.saml.saml_app_backend)] if { var(txn.saml.saml_app_backend) -m found }
backend bk-spoe
mode tcp
timeout connect 5s
timeout server 30s
server auth-server-spoe 127.0.0.1:12345
backend bk-err
mode http
backend bk-$samlapp
option forwardfor
mode http
server app1 127.0.0.1:3200
timeout connect 30s
timeout server 1m
EOF
Your HAProxy Enterprise hapee-lb.cfg
configuration file should contain values such as these (the corresponding variables are specified as comments):
Create the HAProxy Enterprise SAML Component initialization file
The following variable values will be implemented in the file:
| Your Azure application ID |
| Your Azure Active Directory tenant ID |
| Your sample local application's FQDN |
| Your Azure application's name |
| Application configured in the HAProxy Enterprise SAML Component |
-
Copy the Microsoft Azure example authentication request and logout request templates to the HAProxy Enterprise configuration directory:
$ sudo cp /etc/hapee-extras/saml_examples/azure/*.xml /etc/hapee-extras/
-
Create the HAProxy Enterprise SAML Component
saml.ini
initialization file:$ cat <<EOF | sudo tee /etc/hapee-extras/saml.ini config_version = 1.0.0 [$samlapp] {{IDP_APP_NAME}} = $myazureapp {{IDP_APP_ID}} = $idp_app_id {{IDP_TENANT_ID}} = $idp_tenant_id {{CLAIM_PREFIX}} = http://schemas.xmlsoap.org/ws/2005/05/identity/claims {{APP_FQDN}} = $myappfqdn {{APP_LOGIN_URL}} = https://{{APP_FQDN}}/saml/reply {{APP_LOGOUT_URL}} = https://{{APP_FQDN}}/saml/logout {{APP_BACKEND}} = bk-{{APP_NAME}} saml_cookie_secure = 0 saml_cookie_samesite = Lax saml_cookie_httponly = 0 saml_cookie_lifetime = 3600 saml_cookie_time_offset = 0 saml_cookie_domain = {{APP_FQDN}} authn_request_template_filename = authn_request.xml logout_request_template_filename = logout_request.xml saml_app_backend = {{APP_BACKEND}} signing_algo=rsa-sha1 signing_key=/etc/hapee-extras/key.pem sign_authn_requests=1 sign_logout_requests=1 verify_signature=0 app_login_url = {{APP_LOGIN_URL}} app_logout_url = {{APP_LOGOUT_URL}} idp_public_cert = $myazureapp.cer idp_login_url = https://login.microsoftonline.com/{{IDP_TENANT_ID}}/saml2 idp_logout_url = https://login.microsoftonline.com/logout.srf ; this field is also used to detect redirect loops between the IDp and our app idp_referer_url = https://login.microsoftonline.com/ on_saml_response check_schema on_saml_response check_attr entity_id spn:{{IDP_APP_ID}} on_saml_response check_attr version on_saml_response check_attr status_code on_saml_response check_attr issuer https://sts.windows.net/{{IDP_TENANT_ID}}/ on_saml_response check_attr issue_instant on_saml_response check_attr destination {{APP_LOGIN_URL}} on_saml_response check_attr assertion required_count=1 on_saml_response check_conditions required_count=1 on_saml_response check_subject_confirmation_data required_count=1 ; Get all the SAML attributes names on_saml_response check_attr set_var=all_attributes_names set_var_sep=| xpath=/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute/@Name ; Get all the SAML attributes values on_saml_response check_attr set_var=all_attributes_values set_var_sep=| xpath=/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute/saml:AttributeValue/text() ; Get the User Display Name provided in SAML Responses or Logout Requests on_saml_response check_attr set_var=display_name xpath=/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name='http://schemas.microsoft.com/identity/claims/displayname']/@Name on_saml_response check_attr set_var=AuthnInstant_ts xpath=/samlp:Response/saml:Assertion/saml:AuthnStatement/@AuthnInstant set_var_as_timestamp on_saml_response check_attr set_var=AuthnInstant xpath=/samlp:Response/saml:Assertion/saml:AuthnStatement/@AuthnInstant on_logout_request check_attr set_var=display_name xpath=/samlp:LogoutRequest/saml:NameID/text() on_logout_request check_attr destination {{APP_LOGOUT_URL}} required on_logout_request check_attr issuer https://sts.windows.net/{{IDP_TENANT_ID}}/ required EOF
Your HAProxy Enterprise SAML Component saml.ini
initialization file should contain values such as these (the corresponding variables are specified as comments):
Start HAProxy Enterprise and the HAProxy Enterprise SAML Component
Start HAProxy Enterprise and HAProxy Enterprise SAML Component:
This step uses the following variable:
$hapeeversion
-
HAProxy Enterprise version used in paths and binary files names.
$ sudo systemctl enable hapee-extras-spoa-saml
$ sudo systemctl start hapee-extras-spoa-saml
$ sudo systemctl enable hapee-$hapeeversion-lb
$ sudo systemctl start hapee-$hapeeversion-lb
Connect to your sample local application
-
Redirect your NGNIX instance's Fully Qualified Domain Name to
127.0.0.1
in the/etc/hosts
file:This step uses the following variable:
$myappfqdn
Your sample local application's FQDN
$ echo "127.0.0.1 $myappfqdn" | sudo tee -a /etc/hosts
-
Connect to your sample local application's Fully Qualified Domain Name via a web browser.
Connect to
http://app.example.local
orhttps://app.example.local
. -
Sign on to the Microsoft Azure portal with your Microsoft Azure credentials.
The NGINX instance's welcome page displays.
Allow or block usernames
You can allow or block users at the Service Provider level, whatever the Identity Provider.
Copy the first name of one or several users who have access to your Azure Active Directory enterprise application from their user profiles.
-
Add a variable for the list of authorized user's first names to your
.bashrc
file:$ echo 'samlappusers="<Space delimited list of users' first names>"' >> ~/.bashrc
$ echo 'samlappusers="'Elena John Mary\\ Lou'"' >> ~/.bashrc
-
Reload your
.bashrc
file to take into account the variables you've created:$ . .bashrc
-
Insert the following directive in the HAProxy Enterprise SAML Component
saml.ini
initialization file:on_saml_response check_subject_confirmation_data/a on_saml_response check_attr optional set_var_cnt set_var=
givenname xpath=/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"]/saml:AttributeValue/text()'$ sudo sed -i '/on_saml_response check_subject_confirmation_data/a on_saml_response check_attr optional set_var_cnt set_var=givenname xpath=/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"]/saml:AttributeValue/text()' /etc/hapee-extras/saml.ini
-
Insert the following directive in the HAProxy Enterprise
hapee-lb.cfg
configuration file'sfrontend ft-saml
section:frontend ft-saml http-request deny if ! { var(txn.saml.<Internal name for your sample local application>.givenname) <Space delimited list of users' first names> }"
http-request deny if ! { var(txn.saml.MySAMLApp.givenname) Elena John Mary\ Lou }"
$ sudo sed -i "/http-request deny/a \ http-request deny if ! { var(txn.saml.$samlapp.givenname) $samlappusers }" /etc/hapee-$hapeeversion/hapee-lb.cfg
-
Restart HAProxy Enterprise and HAProxy Enterprise SAML Component:
$ sudo systemctl reload hapee-$hapeeversion-lb $ sudo systemctl stop hapee-extras-spoa-saml $ /opt/hapee-extras/bin/hapee-saml -C /etc/hapee-extras -f /etc/hapee-extras/saml.ini
Sign on to your sample local application with an allowed username, then with another username.
Next up
SAML configuration options