Wednesday, 2 March 2016

Customize Web Client Login Page

Written by Suhas Savkoor



Bored of the same blue screen login for vSphere Web Client? Well, don't be bored any more. If you are running 6.0 VMware, then there's a bunch of good news. You can have your own welcome screen for Web Client. Yes, you heard me right!

Web Client login page for 6.0, is designed using HTML and CSS, and when you have this, you can tweak around a little to customize your own page. With the help of William Lam's article, I was able to tweak my Web Client Appearance.

This is how it looks now!



So, here is the bigger story of how to get this done:

>> The first thing is, you need to be on 6.x vCenter, this is not going to work with any other versions of vCenter.
>> There are three files to be altered: the img file, the login.css file and the unpentry.jsp file

Location of these files:

Windows vCenter:

  • C:\ProgramData\VMware\vCenterServer\runtime\VMwareSTSService\webapps\websso\WEB-INF\views\unpentry.jsp
  • C:\ProgramData\VMware\vCenterServer\runtime\VMwareSTSService\webapps\websso\resources\css\login.css
  • C:\ProgramData\VMware\vCenterServer\runtime\VMwareSTSService\webapps\websso\resources\img

VCSA 6.0
  • /usr/lib/vmware-sso/vmware-sts/webapps/websso/WEB-INF/views/unpentry.jsp
  • /usr/lib/vmware-sso/vmware-sts/webapps/websso/resources/css/login.css
  • /usr/lib/vmware-sso/vmware-sts/webapps/websso/resources/img

>> This has to be modified on the machine where your Platform Services Controller is installed. If it is an embedded installation, then you can find it all in one machine. If it is an external PSC deployment, then all these file locations are on the PSC machine.

>> I am using a 6.0 vCenter Appliance with External PSC, so I used WinSCP to transfer files from my desktop to the appliance. 

>> If you are using appliance with WinSCP, then you need to set the bash shell to be opened as default. To do this, you can use this article here

**Have a backup of all these three above files before you make any changes**

The procedure:

>> Download a required image and save it as "AppBgPattern.png" (PNG format), as this naming convention would eliminate editing certain lines in the CSS/JSP file. 

>> Login to WinSCP and browse to the "img" directory as mentioned above and paste this copied image

This takes care of the background image for the Web Client. 

Now, you will have to edit the unpentry.jsp file to reflect the text message. 

>> Once the backup of unpentry.jsp file is made from it's location, open the file and copy paste the below text into it:


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html class="base-app-style">
<!--[if lte IE 8]>
   <link rel="stylesheet" type="text/css" href="../../resources/css/loginIE8-7.css" />
 <![endif]-->
 <!--[if (gte IE 9)|!(IE)]><!-->
   <!--<link href="../../resources/css/login.css" rel="stylesheet"> -->
 <!--<![endif]-->
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=5, IE=8, IE=10" >
   <title>Login</title>

   <script type="text/javascript">
    // copying JSP variables to JS
    var tenant_brandname="${tenant_brandname}";
    var searchString ="${searchstring}";
    var replaceString ='${replacestring}';
    var error = '${error}';
    var errorSSPI = '${errorSSPI}'
   </script>

   <script type="text/javascript" src="../../resources/js/assets/csd_api_common.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_connection.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_base.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_factory.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_config.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_logging.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_session.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_sspi.js"></script>
   <script type="text/javascript" src="../../resources/js/assets/csd_api_sso.js"></script>

   <script type="text/javascript" src="../../resources/js/Base64.js"></script>
   <script type="text/javascript" src="../../resources/js/VmrcPluginUtil.js"></script>
   <script type="text/javascript" src="../../resources/js/CspPluginInstance.js"></script>
   <script type="text/javascript" src="../../resources/js/jquery-1.8.1.js"></script>
   <script type="text/javascript" src="../../resources/js/websso.js"></script>

   <link rel="icon" type="image/x-icon" href="../../resources/img/favicon.ico" />
   <link rel="SHORTCUT ICON" href="../../resources/img/favicon.ico" />
</head>
<body>

<script type="text/javascript">
    // regex to check for internet explorer 11 and below
    var isInternetExplorer = /MSIE (\d+\.\d+);/.test(navigator.userAgent) || /Trident\/(\d+\.\d+);.*rv:(\d+\.\d+)/.test(navigator.userAgent);
    if (!isVCLogin()) {
        document.write('<link rel="stylesheet" type="text/css" href="../../resources/css/login_generic.css">');
    }
    else {
        document.write('<link rel="stylesheet" type="text/css" href="../../resources/css/login.css">');
    }
</script>


<script type="text/javascript">
//createProbes();
//createVmrcPluginObject();
//var _cspId = createCspPluginObject();
if (isVCLogin()) {
    //document.write("<img id=\"topSplash\" src=\"../../resources/img/AppBgPattern.png\"/>");
    document.write("<img id=\"brand\" src=\"../../resources/img/vmwareLogoBigger.png\" />");
}
else {
    document.write("<p id=\"tenantBrand\">"+tenant_brandname+"</p>");
}
</script>

<div id="loginForm">
   <p class="loginRow" >
      <span class="loginLabel">${username}:</span>
      <input id="username" class="margeTextInput" type="text" />
    </p>
    <p class="loginRow" >
      <span class="loginLabel">${password}:</span>
      <input id="password" class="margeTextInput" type="password" />
    </p>
    <p id="sessionID">
       <label id="checkboxLabel"><input id="sspiCheckbox" disabled="true" type="checkbox" onchange='enableSspi(this);'/>${winSession}</label>
    </p>
    <p id="loginButtonRow">
       <input id="submit" class="button blue" type="submit" value=${login} onclick="submitentry()"/>
    </p>
</div>

<div id="productName">
Welcome To South Park</br></br>
   <script type="text/javascript">
        if (isVCLogin()) {
           document.write("<img id=\"VCSSO-Title\" src=\"../../resources/img/VCSSO-title.png\" />");
           }
   </script>
   </br></br>
   <div id="response" style="display:none"></div>
   <div id="progressBar" style="display:none"><img src="../../resources/img/Marge-anim-progressbar.gif"></div>
</div>

<div id="footer" class="footer">
    <span id="downloadCIPlinkBox" style="display:none">
       <a id="downloadCIPlink" target="_blank">${downloadCIP}</a>
    </span>
</div>
<div id="postForm"></div>

<div class="browser-validation-banner" style="visibility: hidden">
   <span class="validation-message-text">${unsupportedBrowserWarning}</span>
</div>

<script type="text/javascript">
   if (isVCLogin() && !isBrowserSupportedVC()) {
      $(".browser-validation-banner").css("visibility","visible");
   }
</script>

</body>
</html>



The text highlighted in "Red" can be edited to display the required message. 

>> Save this file


Next, we will have to edit the CSS file to apply colors and font size to this field or any other field as per requirement:

>> Go to the directory where the CSS file is and simply paste the below code:


@charset "utf-8";
/* CSS Document Login.css */

.base-app-style {
   min-width: 1024px;
   min-height: 612px;
   position: relative;
   height: 100%;
   width: 100%;
}

body {
   background: #3075ab; /* Old browsers */
   background: -moz-linear-gradient(top,  #3a8dc8 0%, #183a62 100%); /* FF3.6+ */
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3a8dc8), color-stop(100%,#183a62)); /* Chrome,Safari4+ */
   background: -webkit-linear-gradient(top,  #3a8dc8 0%,#183a62 100%); /* Chrome10+,Safari5.1+ */
   background: -o-linear-gradient(top,  #3a8dc8 0%,#183a62 100%); /* Opera 11.10+ */
   background: -ms-linear-gradient(top,  #3a8dc8 0%,#183a62 100%); /* IE10+ */
   background: linear-gradient(to bottom,  #3a8dc8 0%,#183a62 100%); /* W3C */
   filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3a8dc8', endColorstr='#183a62',GradientType=0 ); /* IE6-9 */
   background-image: url(../../resources/img/AppBgPattern.png);
   background-repeat:no-repeat;
   margin: 0;
   font-size:12px;
   font-family:Arial, Helvetica, sans-serif;
   color: #87ceff;
}

.browser-validation-banner {
   padding: 6px 12px 6px 10px;
   margin: 0px;
   position: absolute;
   line-height: 20px;
   top: 0px;
   left: 0px;
   right: 0px;
   z-index: 100;
   background-color: #ffffcc;
   border: 1px solid #efe69b;
   border-top-style: none;
   border-radius: 0 0 5px 5px;
   color: #333333;
   box-shadow: 0 3px 3px rgba(0, 0, 0, 0.15);
}

.validation-message-text {
   margin-left: 25px;
   display: block;
   font-weight: bold;
   font-size: 11px;
}

#topSplash {
   position: absolute;
   top:0;
   left:0;
   z-index:1;
}

#brand {
   position: absolute;
   top: 55px;
   left: 120px;
   z-index:2;
}

#loginForm {
   position: absolute;
   top: 320px;
   width: 405px;
   padding-left: 44px;
   z-index:3;

   background-image:url(../img/divider.png);
   background-position:right;
   background-repeat:repeat-y;
}

.margeTextInput {
   float:right;
   margin-right: 44px;
   width:200px;

}

.loginLabel {
   font-weight:bold;
    color: #FFFFFF;

   text-align:left;
   display:block;
   padding-top:4px;

   float:left;
}

.loginRow {
   display:block;
   padding-top:20px;
}

#sessionID {
   clear:both;
   float:right;
   width:248px;
   text-align:left;
   margin-top:8px;
}

#checkboxLabel {
    display: block;
    padding-left: 20px;
    text-indent: -20px;
}

#sspiCheckbox {
    width: 13px;
    height: 13px;
    padding: 0;
    margin:0;
    margin-right:10px;
    vertical-align: bottom;
    position: relative;
    top: -1px;
    left: 5px;
    *overflow: hidden;
}

#loginButtonRow {
   clear: both;
   float:right;
   margin-right:40px;
   margin-top:0px;
}

.button {
   display: inline-block;
   zoom: 1; /* zoom and *display = ie7 hack for display:inline-block */
   *display: inline;
   vertical-align: baseline;
   margin: 0 2px;
   outline: none;
   cursor: pointer;
   text-align: center;
   text-decoration: none;
   padding: 0px 30px;
   height:24px;
   font-size:12px;
}
.button:hover {
   text-decoration: none;
}
.button:active {
   position: relative;
   top: 1px;
}

.blue {
   color: #fff;
   border: solid 2px #1d4772;
   background: #0095cd;
   background: -webkit-gradient(linear, left top, left bottom, from(#0c6fb9), to(#014781));
   background: -moz-linear-gradient(top,  #0c6fb9,  #014781);
   filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#0c6fb9', endColorstr='#014781');
}
.blue:hover {
   background: #007ead;
   background: -webkit-gradient(linear, left top, left bottom, from(#0d84dc), to(#004d88));
   background: -moz-linear-gradient(top,  #0d84dc,  #004d88);
   filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#0d84dc', endColorstr='#004d88');
}
.blue:active {
   color: #fff;
   background: -webkit-gradient(linear, left top, left bottom, from(#035a9d), to(#086fba));
   background: -moz-linear-gradient(top,  #035a9d,  #086fba);
   filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#035a9d', endColorstr='#086fba');
}

#username:disabled,
#password:disabled,
#submit:disabled,
#sspiCheckbox:disabled {
   opacity:0.3;
   filter:alpha(opacity=30); /* For IE8 and earlier */
}


#productName {
   position: absolute;
   top: 345px;
   left:499px;
   color:#F88017;
   font-size:23px;
}

#response {
    background:url(../../resources/img/error.png) left center no-repeat;
    margin-top: 20px;
    font-size: 12.5px;
    padding-left: 20px;
    color: #87CEFF;
}

#rolo {
    font-weight: bold;
    margin-top: 20px;
    font-size: 16px;
    padding-left: 10px;
    color: #FF3333;
}

#progressBar {
   display: none;
}

.footer {
   background-color: black;
   position: absolute;
   left: 0px;
   right: 0px;
   bottom: 0px;
   font-weight: bold;
   padding: 10px;
   color: #7B7E81;
   padding-left: 44px
}

.footer a {
   color : #7B7E81;
   text-decoration: none;
}

.footer a:hover{
   text-decoration: underline;
}

.info-icon {
   display: inline-block;
   width: 16px;
   height: 16px;
   line-height: 16px;
   vertical-align: middle;
   background-repeat: no-repeat;
   margin: 0px 4px 0;
   position: relative;
   background-image: url(../../resources/img/infoOver.png);
   cursor: pointer;
}



The text highlighted in red, is the part to Edit the Product area text. if you want to change the colors of the remaining sections, find the appropriate ones in the CSS file and change them. 

>> Save this file as well. 

>> Reload your Web Client

And that's it, you have your own custom Web Client Login Page.
You can find more samples on GitHub, click here

Enjoy!