Skip to main content

Customizing Qlik Sense Forms Login Page

100% helpful (1/1)
cancel
Showing results for 
Search instead for 
Did you mean: 
Sonja_Bauernfeind
Digital Support
Digital Support

Customizing Qlik Sense Forms Login Page

Last Update:

Jul 13, 2023 6:42:47 AM

Updated By:

Sonja_Bauernfeind

Created date:

Aug 9, 2022 10:26:10 AM

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.

qlik login page default.png

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

This customization is provided as is. Qlik Support cannot provide continued support of the solution. For assistance, reach out to our Professional Services or engage in our active Integrations forum.

To customize the page:

  1. We highly recommend setting up a new virtual proxy with Forms so you don't impact any users that are using auto-login Windows auth.

    Example setup:

    Description: Custom Forms Page
    Prefix: customlogin
    Session cookie header-name: X-Qlik-Session-CustomLogin
    Windows authentication pattern: Forms

    setup custom login page in qmc.png

  2. 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, go to 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.

  3. 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.

  4. 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.

  5. 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"
    }

     

  6. 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):

    custom login page.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.

 

Environment:

Qlik Sense Enterprise on Windows 

Labels (1)
Comments
saso70
Partner - Creator II
Partner - Creator II

Hi Sonja can you please explain to me how to send request via postman? this part i can not put to work GET request  on /qrs/proxyservice and find the ID of the proxy service

Thank you

Sonja_Bauernfeind
Digital Support
Digital Support

Hello @saso70 

This should help QRS API using Xrfkey header in Postman Chrome Extension.

If you require further assistance, I would recommend posting about it directly in our Extensions and APIs forum.

All the best,
Sonja

 

 

B_Duncan
Partner - Contributor II
Partner - Contributor II

Thank you Sonja for this great article. I see that there is also a "errorPageTemplate" setting. How can you update that page and still have it show the dynamic error number and message?

Sonja_Bauernfeind
Digital Support
Digital Support

Hello @B_Duncan 

We have previously received confirmation from R&D that the error Template page cannot be customized.

If you want to see this or a similar functionality introduced into the on-premise product, please log an idea on our ideation page

All the best,
Sonja 

kfat
Contributor
Contributor

Thank you very much, it worked. It fully met the need.

ryanocni
Contributor III
Contributor III

Hi @Sonja_Bauernfeind ,

I got 404 error, in step 2. When accessing https://myserver.com/customlogin/internal_forms_authentication.
Please help

Thanks

Sonja_Bauernfeind
Digital Support
Digital Support

Hello @ryanocni 

This would indicate that you do not have access to this file. I would recommend posting about your issue in the appropriate forums to be able to get more eyes on the issue. In your case, the forum would be the Integrations and API forum.

All the best,
Sonja 

ShayBitton1
Contributor
Contributor

hi @ryanocni 

It faced that too, my problem was that i forgot to insert the site address in the whitelist

Best

Shay

PierreBizzotto
Contributor
Contributor

Hi @Sonja_Bauernfeind,

sorry for the necroposting.

I followed your guide and completed all the steps successfully: now my login page is customized.

However something is wrong: I don't see the error messages if I get my username or password wrong and the page, in case of correct login, doesn't redirect to the hub.

Do you have any tips?

Thank you,

Pierre

Sonja_Bauernfeind
Digital Support
Digital Support

Hello @PierreBizzotto 

Our professional services can be engaged for direct assistance with this customization. See Professional Services. Alternatively, you can reach out to our larger userbase with your customization requirement in the Integrations forum.

All the best,
Sonja 

Version history
Last update:
‎2023-07-13 06:42 AM
Updated by: