Qlik Community

Qlik Architecture Deep Dive Blog

Deep dives into specific back-end technologies which allow for the extension of Qlik to fit the needs of the enterprise.

Employee
Employee

Ever wanted to brand or customize the default Qlik Sense Login page? The functionality exists, and it's really as simple as just designing your HTML page and 'POSTing' it into your environment.

Screen Shot 2020-05-20 at 11.44.22 AM.png

We've all seen the standard Qlik Sense Login page, this article is all about customizing this page.

When getting started, I would strongly recommend setting up a new virtual proxy with 'Forms' so you don't impact any users that are using auto-login Windows auth.

The virtual proxy settings would look something like this:

Screen Shot 2020-05-20 at 11.51.51 AM.png

 

Now once this is done, a good starting point is to download the default login page. You can open up your web developer tool of choice, goto the login page, and download the html response from the GET http://<server>/customlogin/internal_forms_authentication request. It should be roughly a 273 line .html file.

Once you have this file, you can more or less customize it as much as you'd like. Image files can be inlined as you'll see in the qlik default file, or can be referenced as long as they are publicly accessible. The only thing that NEEDS to exist are the input boxes with appropriate classes and attributes, and the 'Log In' button.

After building out your custom html page and it looks great, it needs to be converted to Base64. There are online tools to do this, openssl also has this functionality.

Once you HAVE your Base64 encoded HTML file, then you will want to PUT it into your sense environment.

First, do a GET request  on /qrs/proxyservice and find the ID of the proxy service you want this login page to be shown for.

You will then do a GET request on /qrs/proxyservice/<id> and copy the body of that response. Below is an example of that response.

 

 

{
    "id": "8817d7ab-e9b2-4816-8332-f8cb869b27c2",
    "createdDate": "2020-03-23T15:39:33.540Z",
    "modifiedDate": "2020-05-20T18:46:13.995Z",
    "modifiedByUserName": "INTERNAL\\sa_api",
    "customProperties": [],
    "settings": {
        "id": "8817d7ab-e9b2-4816-8332-f8cb869b27c2",
        "createdDate": "2020-03-23T15:39:33.540Z",
        "modifiedDate": "2020-05-20T18:46:13.995Z",
        "modifiedByUserName": "INTERNAL\\sa_api",
        "listenPort": 443,
        "allowHttp": true,
        "unencryptedListenPort": 80,
        "authenticationListenPort": 4244,
        "kerberosAuthentication": false,
        "unencryptedAuthenticationListenPort": 4248,
        "sslBrowserCertificateThumbprint": "e6ee6df78f9afb22db8252cbeb8ad1646fa14142",
        "keepAliveTimeoutSeconds": 10,
        "maxHeaderSizeBytes": 16384,
        "maxHeaderLines": 100,
        "logVerbosity": {
            "id": "8817d7ab-e9b2-4816-8332-f8cb869b27c2",
            "createdDate": "2020-03-23T15:39:33.540Z",
            "modifiedDate": "2020-05-20T18:46:13.995Z",
            "modifiedByUserName": "INTERNAL\\sa_api",
            "logVerbosityAuditActivity": 4,
            "logVerbosityAuditSecurity": 4,
            "logVerbosityService": 4,
            "logVerbosityAudit": 4,
            "logVerbosityPerformance": 4,
            "logVerbositySecurity": 4,
            "logVerbositySystem": 4,
            "schemaPath": "ProxyService.Settings.LogVerbosity"
        },
        "useWsTrace": false,
        "performanceLoggingInterval": 5,
        "restListenPort": 4243,
        "virtualProxies": [
            {
                "id": "58d03102-656f-4075-a436-056d81144c1f",
                "prefix": "",
                "description": "Central Proxy (Default)",
                "authenticationModuleRedirectUri": "",
                "sessionModuleBaseUri": "",
                "loadBalancingModuleBaseUri": "",
                "useStickyLoadBalancing": false,
                "loadBalancingServerNodes": [
                    {
                        "id": "f1d26a45-b0dd-4be1-91d0-34c698e18047",
                        "name": "Central",
                        "hostName": "qlikdemo",
                        "temporaryfilepath": "C:\\Users\\qservice\\AppData\\Local\\Temp\\",
                        "roles": [
                            {
                                "id": "2a6a0d52-9bb4-4e74-b2b2-b597fa4e4470",
                                "definition": 0,
                                "privileges": null
                            },
                            {
                                "id": "d2c56b7b-43fd-44ad-a12f-59e778ce575a",
                                "definition": 1,
                                "privileges": null
                            },
                            {
                                "id": "37244424-96ae-4fe5-9522-088a0e9679e3",
                                "definition": 2,
                                "privileges": null
                            },
                            {
                                "id": "b770516e-fe8a-43a8-a7a4-318984ee4bd6",
                                "definition": 3,
                                "privileges": null
                            },
                            {
                                "id": "998b7df8-195f-4382-af18-4e0c023e7f1c",
                                "definition": 4,
                                "privileges": null
                            },
                            {
                                "id": "2a5325f4-649b-4147-b0b1-f568be1988aa",
                                "definition": 5,
                                "privileges": null
                            }
                        ],
                        "serviceCluster": {
                            "id": "b07fc5f2-f09e-4676-9de6-7d73f637b962",
                            "name": "ServiceCluster",
                            "privileges": null
                        },
                        "privileges": null
                    }
                ],
                "authenticationMethod": 0,
                "headerAuthenticationMode": 0,
                "headerAuthenticationHeaderName": "",
                "headerAuthenticationStaticUserDirectory": "",
                "headerAuthenticationDynamicUserDirectory": "",
                "anonymousAccessMode": 0,
                "windowsAuthenticationEnabledDevicePattern": "Windows",
                "sessionCookieHeaderName": "X-Qlik-Session",
                "sessionCookieDomain": "",
                "additionalResponseHeaders": "",
                "sessionInactivityTimeout": 30,
                "extendedSecurityEnvironment": false,
                "websocketCrossOriginWhiteList": [
                    "qlikdemo",
                    "qlikdemo.local",
                    "qlikdemo.paris.lan"
                ],
                "defaultVirtualProxy": true,
                "tags": [],
                "samlMetadataIdP": "",
                "samlHostUri": "",
                "samlEntityId": "",
                "samlAttributeUserId": "",
                "samlAttributeUserDirectory": "",
                "samlAttributeSigningAlgorithm": 0,
                "samlAttributeMap": [],
                "jwtAttributeUserId": "",
                "jwtAttributeUserDirectory": "",
                "jwtAudience": "",
                "jwtPublicKeyCertificate": "",
                "jwtAttributeMap": [],
                "magicLinkHostUri": "",
                "magicLinkFriendlyName": "",
                "samlSlo": false,
                "privileges": null
            },
            {
                "id": "a8b561ec-f4dc-48a1-8bf1-94772d9aa6cc",
                "prefix": "header",
                "description": "header",
                "authenticationModuleRedirectUri": "",
                "sessionModuleBaseUri": "",
                "loadBalancingModuleBaseUri": "",
                "useStickyLoadBalancing": false,
                "loadBalancingServerNodes": [
                    {
                        "id": "f1d26a45-b0dd-4be1-91d0-34c698e18047",
                        "name": "Central",
                        "hostName": "qlikdemo",
                        "temporaryfilepath": "C:\\Users\\qservice\\AppData\\Local\\Temp\\",
                        "roles": [
                            {
                                "id": "2a6a0d52-9bb4-4e74-b2b2-b597fa4e4470",
                                "definition": 0,
                                "privileges": null
                            },
                            {
                                "id": "d2c56b7b-43fd-44ad-a12f-59e778ce575a",
                                "definition": 1,
                                "privileges": null
                            },
                            {
                                "id": "37244424-96ae-4fe5-9522-088a0e9679e3",
                                "definition": 2,
                                "privileges": null
                            },
                            {
                                "id": "b770516e-fe8a-43a8-a7a4-318984ee4bd6",
                                "definition": 3,
                                "privileges": null
                            },
                            {
                                "id": "998b7df8-195f-4382-af18-4e0c023e7f1c",
                                "definition": 4,
                                "privileges": null
                            },
                            {
                                "id": "2a5325f4-649b-4147-b0b1-f568be1988aa",
                                "definition": 5,
                                "privileges": null
                            }
                        ],
                        "serviceCluster": {
                            "id": "b07fc5f2-f09e-4676-9de6-7d73f637b962",
                            "name": "ServiceCluster",
                            "privileges": null
                        },
                        "privileges": null
                    }
                ],
                "authenticationMethod": 1,
                "headerAuthenticationMode": 1,
                "headerAuthenticationHeaderName": "userid",
                "headerAuthenticationStaticUserDirectory": "QLIKDEMO",
                "headerAuthenticationDynamicUserDirectory": "",
                "anonymousAccessMode": 0,
                "windowsAuthenticationEnabledDevicePattern": "Windows",
                "sessionCookieHeaderName": "X-Qlik-Session-Header",
                "sessionCookieDomain": "",
                "additionalResponseHeaders": "",
                "sessionInactivityTimeout": 30,
                "extendedSecurityEnvironment": false,
                "websocketCrossOriginWhiteList": [
                    "qlikdemo",
                    "qlikdemo.local"
                ],
                "defaultVirtualProxy": false,
                "tags": [],
                "samlMetadataIdP": "",
                "samlHostUri": "",
                "samlEntityId": "",
                "samlAttributeUserId": "",
                "samlAttributeUserDirectory": "",
                "samlAttributeSigningAlgorithm": 0,
                "samlAttributeMap": [],
                "jwtAttributeUserId": "",
                "jwtAttributeUserDirectory": "",
                "jwtAudience": "",
                "jwtPublicKeyCertificate": "",
                "jwtAttributeMap": [],
                "magicLinkHostUri": "",
                "magicLinkFriendlyName": "",
                "samlSlo": false,
                "privileges": null
            }
        ],
        "formAuthenticationPageTemplate": "",
        "loggedOutPageTemplate": "",
        "errorPageTemplate": "",
        "schemaPath": "ProxyService.Settings"
    },
    "serverNodeConfiguration": {
        "id": "f1d26a45-b0dd-4be1-91d0-34c698e18047",
        "name": "Central",
        "hostName": "qlikdemo",
        "temporaryfilepath": "C:\\Users\\qservice\\AppData\\Local\\Temp\\",
        "roles": [
            {
                "id": "2a6a0d52-9bb4-4e74-b2b2-b597fa4e4470",
                "definition": 0,
                "privileges": null
            },
            {
                "id": "d2c56b7b-43fd-44ad-a12f-59e778ce575a",
                "definition": 1,
                "privileges": null
            },
            {
                "id": "37244424-96ae-4fe5-9522-088a0e9679e3",
                "definition": 2,
                "privileges": null
            },
            {
                "id": "b770516e-fe8a-43a8-a7a4-318984ee4bd6",
                "definition": 3,
                "privileges": null
            },
            {
                "id": "998b7df8-195f-4382-af18-4e0c023e7f1c",
                "definition": 4,
                "privileges": null
            },
            {
                "id": "2a5325f4-649b-4147-b0b1-f568be1988aa",
                "definition": 5,
                "privileges": null
            }
        ],
        "serviceCluster": {
            "id": "b07fc5f2-f09e-4676-9de6-7d73f637b962",
            "name": "ServiceCluster",
            "privileges": null
        },
        "privileges": null
    },
    "tags": [],
    "privileges": null,
    "schemaPath": "ProxyService"
}

 

 

  

You can then take your base64 encoded HTML file, paste that value into the 'formAuthenticationPageTemplate' field. Once you have an updated body, you can use the PUT verb (with an updated modifiedDate) to PUT this body back into the repository. Once this is done, you should be able to goto your virtual proxy and you should see your new login page (very Qlik branded in this example):

Screen Shot 2020-05-20 at 11.46.31 AM.png

 

If your login page does NOT work, you can simply do a GET call on your proxy service, and set formAuthenticationPageTemplate back to an empty string:

 

 

formAuthenticationPageTemplate": ""

 

 

 

Once this is done, you should get reverted back to the default login screen.

Tags (1)
4 Comments
Employee
Employee

This is fantastic! Great job, as always, Jesse!

1,285 Views
Specialist II
Specialist II

Hi @Jesse_Paris ,

it is magnificently and really on time !

Thanks a lot

0 Likes
1,076 Views
Partner
Partner

Great Job!

I dont understand why Qlik doesn't offer a friendly functionality for login form personalization....

0 Likes
1,022 Views
Specialist III
Specialist III

Hi Jesse,

Can you please share sample html file with me, so I can modify it and test it. I am BI person, has no Knowledge of HTML.

 

Thanks,

Rohit

0 Likes
469 Views