Deep dives into specific back-end technologies which allow for the extension of Qlik to fit the needs of the enterprise.
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:
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):
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.