HAProxy Enterprise Documentation 2.3r1

SAML Reference

Reference guide

HAProxy Enterprise hapee-lb.cfg configuration file sections

Frontend

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(MySAMLApp) if { hdr(host) -i app.example.local }
    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 displayname           %[var(txn.saml.displayname)]
    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 }

Key directives

frontend ft-saml

Declare a SAML frontend to redirect user requests to HAProxy Enterprise SAML Component.

    bind :80

Listen to incoming traffic over HTTP and HTTPS.

    bind :443 ssl crt mycert.pem

Listen to incoming traffic over HTTPS and enable SSL termination. The CRT parameter identifies the PEM-formatted SSL certificate location. This certificate should contain both the HAProxy Enterprise server's public certificate and private key.

    option http-buffer-request

Wait for the whole HTTP request body before forwarding it to HAProxy Enterprise SAML Component.

    tcp-request inspect-delay 10s

Set the maximum time to wait for data during content inspection to 10 seconds.

    http-request set-var(sess.saml_app) str(MySAMLApp) if { hdr(host) -i app.example.local }

Set variable sess.saml_app to MySAMLApp if the HTTP request's host header field matches app.example.local, ignoring case.

Note

Replace app.example.local by the section header of your HAProxy Enterprise SAML Component saml.ini initialization file, and edit the ACL as needed. See SAML application backend.

    filter spoe engine spoe-saml config /etc/hapee-extras/hapee-saml-spoe.cfg

Declare the spoe-saml SPOE filter and its /etc/hapee-extras/hapee-saml-spoe.cfg configuration file, to forward streaming data to HAProxy Enterprise SAML Component.

    http-request send-spoe-group spoe-saml spoe-group-req

Send messages to HAProxy Enterprise SAML Component. Define the spoe-group-req group of messages to send via a spoe-group section in the /etc/hapee-extras/hapee-saml-spoe.cfg SPOE configuration file.

    http-request redirect location %[var(txn.saml.redirect_to)] code 302 if   { var(txn.saml.redirect_to) -m found }

Redirect the user to the value of variable txn.saml.redirect_to.

See also

Configuring HAProxy Enterprise for Transport Layer Security (TLS)

Stream Processing Offload Engine (SPOE)

Backends

Add the following backend sections:

Stream Processing Offload Engine backend:

backend bk-spoe
    mode tcp
    timeout connect 5s
    timeout server  30s
    server auth-server-spoe 127.0.0.1:12345

Change the socket address on the server line to match your setup.

You can use the spoa-saml -A and -P options to change the IP address and the port.

Default backend to manage errors

backend bk-err
    mode http

Make it the default backend in the frontend section:

    default_backend bk-err

If no target backend has been set, the fallback backend is bk-err. The user is not granted access and receives a 502 error.

SAML application backend

backend bk-MySAMLApp
    option forwardfor
    mode http
    server app1 127.0.0.1:3200
    timeout connect 30s
    timeout server 1m

Warning

Before sending the HAProxy Enterprise requests to the Stream Processing Offload Agent, you must set the sess.saml_app variable to the name of the application.

This application must have a dedicated section in the HAProxy Enterprise SAML Component saml.ini initialization file.

See also

sess.saml_app

HAProxy Enterprise SAML Component saml.ini initialization file

You can configure several applications in the HAProxy Enterprise SAML Component saml.ini initialization file, one per section.

To configure an application called MySAMLApp, use [MySAMLApp] as the section header.

Configuration options

Actions

Microsoft Azure HAProxy Enterprise SAML Component saml.ini initialization file example

This example is intended to be used with Microsoft Azure. To use HAProxy Enterprise SAML Component with other Identity Providers, this configuration file needs some adjustments.

Variables

{{ID_APP_NAME}}

Name of your application in Azure Active Directory.

{{IDP_APP_ID}}

Application ID provided by the Identity Provider (Azure Active Directory).

For instance: aa0aaaaa-0aa0-000a-a0a0-aa0000a0000a.

/documentation/hapee/latest/assets/azure-application-id-362e3f0f656ad91cf7e4beb21c7f9ddb195bd4b8d0e689e3d976c5cc427e6058.png
{{IDP_TENANT_ID}}

aaa000a0-0000-0a00-0000-000a00a00a0

{{CLAIM_PREFIX}}

http://schemas.xmlsoap.org/ws/2005/05/identity/claims

{{APP_FQDN}}

Fully Qualified Domain Name of the Identity Provider (Azure Active Directory).

dkorunichaproxy.onmicrosoft.com

{{APP_LOGIN_URL}}

Assertion Consumer Service URL, depending on your application. Value of app_login_url for this application.

{{APP_LOGIN_URL}} is automatically replaced if you specify it in the HAProxy Enterprise SAML Component saml.ini initialization file.

https://\{\{APP_FQDN}}/saml/reply

{{APP_LOGOUT_URL}}

Value of app_logout_url for this application.

Logout URL, depending on your application.

https://\{\{APP_FQDN}}/saml/logout

{{APP_BACKEND}}

Backend on which the application is available.

bk-{{APP_NAME}}: {{APP_NAME}} will be replaced with the section name.

If the section header is [MySAMLApp], the backend is called bk-MySAMLApp.

/etc/hapee-extras/saml.ini example
config_version = 1.0.0

[MySAMLApp]
{{ID_APP_NAME}} = xxx  #  the name of your application in Azure AD
{{IDP_APP_ID}} = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{{IDP_TENANT_ID}} = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{{CLAIM_PREFIX}} = http://schemas.xmlsoap.org/ws/2005/05/identity/claims
{{APP_FQDN}} = xxx  #  ex: app1.example.local
{{APP_LOGIN_URL}} = https://{{APP_FQDN}}/saml/reply    # ACS url, depending on your application
{{APP_LOGOUT_URL}} = https://{{APP_FQDN}}/saml/logout  # logout url, depending on your application
{{APP_BACKEND}} = bk-{{APP_NAME}}                      # APP_NAME will be replaced with the section name

saml_cookie_secure = 0
saml_cookie_httponly = 1
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}}

idp_login_url = https://login.microsoftonline.com/{{IDP_TENANT_ID}}/saml2
idp_logout_url = https://login.microsoftonline.com/{{IDP_TENANT_ID}}/saml2
app_login_url = {{APP_LOGIN_URL}}
app_logout_url = {{APP_LOGOUT_URL}}
idp_referer_url = https://login.microsoftonline.com/

on_saml_response check_schema
; idp_public_cert = azure_pub_cert.pem  # in Azure, chose Certificate (Base64) to download a .cer file
; verify_signature=1
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

on_logout_request check_attr destination {{APP_LOGOUT_URL}} required
on_logout_request check_attr issuer https://sts.windows.net/{{IDP_APP_ID}}/ required

on_saml_response check_attr optional set_var_cnt set_var=givenname xpath=/samlp:Response/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name="{{CLAIM_PREFIX}}/givenname"]/saml:AttributeValue/text()

Note

You can use retrieved XML attributes in HTTP rules in the HAProxy Enterprise hapee-lb.cfg configuration file:

  • To restrict acess:

    For instance:

    http-request deny if ! \{ var(txn.givenname) user1 user2 user3 }
  • To set HTTP headers:

    For instance:

    set-header myname %[var(txn.givenname)]

AuthnRequest template

Here is an example of an Authentication Request template. You can send generated AuthnRequests to Microsoft Azure:

authn_request.xml
<samlp:AuthnRequest
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
ID="id%%RANDOM_ID_HEX_32%%"
Version="2.0" IssueInstant="%%NOW_WITH_MS%%"
ForceAuthn="false"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">{{IDP_APP_ID}}</Issuer>
</samlp:AuthnRequest>

You can specify templates via the authn_request_template_filename configuration directive. The path is relative to the configuration directory. You can specify a custom directory via the -C command-line option.

The following patterns are automatically replaced:

%%NOW%%

Current time in ISO 8601 format.

2020-01-28T15:25:14Z

%%NOW_WITH_MS%%

Current time in ISO 8601 format, including milliseconds.

2020-01-28T15:25:14.884Z

%%RANDOM_ID_HEX_32%%

32-char random ID, comprising the following characters: 0123456789abcdef.

%%ISSUER%%

Replace manually by the value expected by your Identity Provider. On Microsoft Azure, you can replace it with:

  • Your Microsoft Azure Application ID

    The entity_id received in the SAML Response is spn:<Application ID>.

    ae7edebf-2db4-476f-b1a9-bf5782b1799a5b25e637

  • The name of your application in Microsoft Azure

    The entity_id received in the SAML Response is this very issuer.

If your application name in this configuration file is the same as the one in Microsoft Azure, you can use {{APP_NAME}}.

ForceAuthn="false"

If set to True, users have to reauthenticate, even if they already have a valid session.

LogoutRequest template

You can use a similar template for Logout Requests:

logout_request.xml
<samlp:LogoutRequest
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
ID="id%%RANDOM_ID_HEX_32%%" Version="2.0" IssueInstant="%%NOW_WITH_MS%%" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
  <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">{{IDP_APP_ID}}</Issuer>
  <NameID xmlns="urn:oasis:names:tc:SAML:2.0:assertion">%%NAME_ID%%</NameID>
</samlp:LogoutRequest>

The following patterns are automatically replaced:

%%ISSUER%%

Value from the SAML Response.

In Microsoft Azure, the following template applies:

https://sts.windows.net/<MS application ID>/

%%NameID%%

Value from the SAML Response, usually the user's email address.

Actions

Action flags

optional

This argument is not required.

required

This argument is mandatory.

nofail

For testing purposes. This action never fails, even if it returns an error.

required_count=<count>

Fails if the number of searched elements is different from <count>.

xpath=<XPath expression>

XPath expression to look for. Use with check_attr actions.

expected=<expected_value>

Fails if the XPath result is different from this expression.

set_var=<var_name>

If one or more XPath results are found, store their values in this variable. The variable name is then prefixed with the application name followed by a dot.

If you set set_var=myvar, the value is available in the HAProxy Enterprise hapee-lb.cfg configuration file via %[var(txn.saml.MySAMLApp.myvar)].

set_var_once

The variable is set only after the POST request from the SAML Identity Provider. Otherwise, it is set each time the SAML cookie is found.

set_var_cnt

The number of XPath results is stored into variable <APP_NAME>.<VAR_NAME>_cnt.

set_var_as_timestamp

If used with a value in ISO 8601 date and time format, the variable is converted to a timestamp.

2020-01-28T15:25:14.884Z

set_var_sep=<separator>

If multiple results are returned from the XPath query, separate them with this character.

set_var_default=<default_value>

Default value used if the XPath expression does not match.

sign_auth_requests

Set to 1 to sign authentication requests.

sign_logout_requests

Set to 1 to sign logout requests.

signing_algo

Cryptographic algorithm used to sign outbound requests.

signing_key

Private key used to sign outbound requests.

verify_signature

Verify the signature of incoming SAML requests.

Running HAProxy Enterprise SAML Component

To run HAProxy Enterprise SAML Component, run the following command:

$ /opt/hapee-extras/bin/hapee-saml -C <config_dir> -f <SAML configuration file>
$ /opt/hapee-extras/bin/hapee-saml -C spoa-saml/examples -f /etc/hapee-extras/saml.ini
Usage

hapee-saml [OPTION]...

-h

Print this message.

-f config_file

.ini file containing the SAML configuration.

-C config_dir

Directory containing the configuration file and the SAML templates.

-l --licenses

Print software licenses.

-v --version

Print product version.

--debug-spoe -d

Debug Stream Processing Offload Engine.

--debug-spoe-variables

Debug Stream Processing Offload Engine variables.

--debug-saml

Debug SAML actions.

--debug-xml

Debug XML parsing.

--debug-config

Debug configuration parsing.

--debug-all

Debug all, except the configuration parsing.

--print-cfg

Display configuration during startup.

--check-cfg -c

Check configuration, then exit.

--gid

Run in the specified group.

--uid

Run as the specified user.

-F

Disable syslog output, and run in the foreground.

-s

Use syslog.

-p <pidfile>

Write the server PID to the specified file.

-A <address>

Listen on this address.

-P <port>

Specify the port to listen on.

Default value: 12345

-n <num-workers>

Specify the number of workers.

-b <conn-backlog>

Specify the connection backlog value.

Default value: 10

Troubleshooting

Debug mode

If requests are denied or authentication fails, you can start the program with --debug-all -F to get more verbose output.

$ hapee-saml -f /etc/hapee-extras/saml.ini --debug-all -F
  1586529662.886993 [00] Config version supported: 1.0.0
  1586529662.887347 [00] Config version 1.0.0
  1586529662.889158 [00] add namespace 0: samlp->urn:oasis:names:tc:SAML:2.0:protocol
  1586529662.889413 [00] add namespace 1: saml->urn:oasis:names:tc:SAML:2.0:assertion
  [...]

Testing XPath expressions

  1. Run HAProxy Enterprise SAML Component in debug mode.

  2. Save the SAML Response to a text file.

  3. Use the xmllint command-line XML tool to test XPath expressions.

    The xmllint command is provided in the libxml2 package.

$ hapee-saml -f /etc/hapee-extras/saml.ini --debug-all -F >> log_file 2>&1

$ xmllint --shell SAMLResponse.xml

setns saml=urn:oasis:names:tc:SAML:2.0:assertion
setns samlp=urn:oasis:names:tc:SAML:2.0:protocol

xpath /samlp:Response/@Destination

Various online XPath test tools are available online. Be careful not to send confidential information.

Infinite loop

If an infinite loop between your application and the Identity Provider occurs when trying to access a resource, check your cookie_secure setting. If set to 1, your browser will only use the cookie for HTTPS, not for plain HTTP.

Before you go into production

  1. Set saml_cookie_secure to 1.

  2. Enable XML signatures if supported by your Identity Provider and your setup.

  3. Depending on how your Identity Provider handles logouts, ensure that the LogoutRequest is sent to your application along with a cookie.

  4. Some Identity Providers' cookies (for example, Azure's) are regarded as third-party (these Identity Providers use an iframe to send the LogoutRequest to your application).

    These cookies might be blocked by your browser, depending on its configuration and the value of the SameSite cookie attribute.

    Set the SameSite to 0 or 1 via the saml_cookie_samesite configuration item.

  5. To test logout, check that the LogoutRequest returns a 200 code and is received by your application.

    Successful LogoutRequests also set the txn.saml.saml_logout_ok HAProxy Enterprise variable to 1.