Warning!
This is a legacy document. The features described below are only usable within the classic-generation environment.
Currently, Betty Blocks offers faster and more advanced options that are available in next-gen. Before you start working on some new features in your application, consider doing it using the next-gen version. Good luck!
After reading this article you will know:
How to create single sign-on via ADFS for frontend applications
For this article it is important that you understand the basics of SAML connections and that you can set-up a SAML provider service.
Note: This tutorial is based on a specific ADFS environment. It serves as an example and doesn't set the standard for all ADFS implementations. Make sure to fully understand the ADFS environment you're working with and adjust the values in your Betty Blocks application to the values required.
Throughout this article we use SAML as an example and will be described what needs to configured to successfully create the connection. Note: choosing a different authentication service might deviate from the settings described in this article.
First we will explain which datamodels you need.
DATAMODELS
WebUser & SamlSetting
These datamodels are needed to successfully use the connection. The model "WebUser" is the center model that is used to authenticate the user within the Betty Blocks application. In the next step we will create an authentication profile for this model.
The model "SamlSetting" is separated from other models so it doesn't have any relations to other models.
Below you'll see an overview of the models and properties. The order of the column is: Property name --> Label --> Property type.
Create an authentication profile to authenticate the user in Betty Blocks
Don't know how to use authentication profiles? Read this article first
Name: SAML
Kind: Custom authentication
Login variable: online_user
Settings
Login model: web_user
Expire: 86400 (standaard)
Login redirect to endpoint: (Own endpoint)
In your back office create a record in the SamlSetting model and fill out the details of your SAML provider.
Example:
idp_sso_target_url: 'https://your-saml-provider.domain.com/adfs/ls/'
issuer: 'mybettybblocksapp'
name_identifier_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
Create Web endpoints to go through the authentication flow
The 2 following pages connect it all together with the action that will be explained later in this article.
Now you create the first page. This is a custom HTML page with the GET Method. In this example we call it "initiate". This page will redirect the user to the ADFS/SAML provider of your choice to authenticate the user via the SSO service. After creating this endpoint you can set it as the redirect endpoint in your authentication profile as well. When a user is not authenticated in Betty Blocks but the endpoint requires an authenticated user, the user will then be automatically redirected to the ADFS/SAML provider.
At this page you create a couple variables add an action that is triggered when this page is used.
The following variables are required:
auth_request_url:
Text Expression (enable liquid parse)
'{{saml_settings.idp_sso_target_url}}?SAMLRequest={{escaped_request}}'
deflation_level:
Number
9
encoded_request:
Text Expression
replace(base64_encode(substring(zlib_deflate(var:xml_auth_request, var:deflation_level), 2, -4)), newline, '')
escaped_request:
Text Expression (enable liquid parse)
'{{encoded_request | url_encode}}'
now:
Date Time Expression
now
saml_settings - Object: Model: SamlSetting , Filter: Id exists
uuid:
Text Expression
generate_uuid()
xml_auth_request:
Text Expression (enable liquid parse)
"<samlp:AuthnRequest Destination='{{saml_settings.idp_sso_target_url}}' ID='_{{uuid}}' IssueInstant='{{now | localize: '%Y-%m-%dT%H:%M:%SZ'}}' Version='2.0' xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol'><saml:Issuer>{{saml_settings.issuer}}</saml:Issuer><samlp:NameIDPolicy AllowCreate='true' Format='{{saml_settings.name_identifier_format}}'/></samlp:AuthnRequest>"
Action
The action that is triggered at the "initiate" page will be called "Redirect to SAML Provider". In this action you add a "Redirect web page event" with response code 302. The redirection URL is the variable you created earlier: var:auth_request_url.
For the 2nd and last page you make a page with XML format and POST method. At this page you create a couple more variables.
This page has 2 input variables:
the following variables are required:
decoded_response:
Text Expression
base64_decode(var:samlresponse, 'string')
name_id:
Text Expression
str(xpath(var:decoded_response, '//NameID/text()', true))
status:
Text Expression
str(xpath(var:decoded_response, '//Status/StatusCode/@Value', true))
user_group:
Text Expression
str(xpath(var:decoded_response, '//Attribute[@Name=" ADFSschema "]/AttributeValue/text()', true))
The template that you use for this page is very simple:
<STATUS>{{status}}/</STATUS>
<NAMEID>{{name_id}}</NAMEID>
Make sure to remove any layout that your page might use here. Since we're building a XML page, we don't need a layout.
Action Login via SAML
Section 1
Condition
Use Expression:
var:status == 'urn:oasis:names:tc:SAML:2.0:status:Success'
Section 2
Redirect web page 302
Path:
'/saml/auth-failed?status=' + var:status
Condition:
use expression:
var:existing_web_user != nil
Variabel
Kind: Object
Name: existing_web_user
Model: web_user
Filter: Username is equal to var:name_id
Section 3
Create
Kind: create
Model: web_user
Assign: (property) username (value) name_id
As: web_user
Authenticate & login user
Kind: Authenticate & Login user
Authentication profile: SAML (Custom authentication)
User variable: var:existing_web_user
Section 4
Authenticate & login user
Kind: Authenticate & login user
Authentication profile: SAML (Custom authentication)
User variable: var:web_user
Section 5
Redirect web page 302
Redirect URL:
Path: '/' (this is the page where you want the user to be redirected to after a succesful authentication.
Your connection should be all set up and ready to test.
Warning: This tutorial is based on a specific ADFS environment.
For certain environments you also need to validate the response you get or post to your login server.
Make sure to check what the security requirements are for your ADFS integration to keep building secure applications.