MicroStrategy ONE

Code Explanation for Scenario: Displaying Different Login Pages based on Project

In this customization scenario, you create both a custom ESM and a custom log-in page. The custom ESM overrides the handlesAuthenticationRequest method with custom code that determines which project was selected and invokes the appropriate login page for that project. It also overrides the getCustomLoginURL method so that it returns a URL that points to the custom login page. The custom login page gathers user credentials and creates an Intelligence Server session..

  • In the custom ESM, you must include the logic to first determine the currently selected project and then invoke either the default login page or a custom login page based on that project.  

  • In the custom log-in page, you must collect all of the information needed to create a session (the user ID and password, authentication mode, server name and port, project, and locale), create the session on Intelligence Server, and pass the session state and other required information back to MicroStrategy Web.

Custom ExternalSecurity java class  (calledDiffLoginPages.javain the corresponding scenario)  

A generic explanation of how to create the custom ESM code required to perform this customization is provided below. The code is explained in sections, with the explanation preceding each section of code.

  • Explanation: Specify the package in which this class will reside and import the necessary classes, including AbstractExternalSecurity (which contains default implementations for all of the methods). Declare that this custom External Security class (compiled from the sample java file called DiffLoginPages.java in the corresponding scenario) extends AbstractExternalSecurity.

    Copy
    package com.microstrategy.sdk.samples.externalsecurity;
    import com.microstrategy.web.app.AbstractExternalSecurity;
    import com.microstrategy.web.app.ExternalSecurity;
    import com.microstrategy.web.beans.RequestKeys;
    import com.microstrategy.web.platform.ContainerServices;
    public class DiffLoginPages extends AbstractExternalSecurity {
  • Explanation: Override the handlesAuthenticationRequest method to add logic that determines whether to use the default login page or a custom login page, based on the project selected. The project is determined using the value of the “Project” key in the RequestKeys parameter. In this simple example, a custom login page is used only if the user selects the MicroStrategy Tutorial project; otherwise, the default login page is used. When a custom login page is used, it must create the session on Intelligence Server. When the default login page is used, MicroStrategy Web takes care of session creation.:

    Copy
        public int handlesAuthenticationRequest(RequestKeys reqKeys, ContainerServices cntSvcs, int reason)
            {
            String strProject = reqKeys.getValue("Project");
     
            if (strProject.equalsIgnoreCase("MicroStrategy Tutorial"))
                {
                return ExternalSecurity.USE_CUSTOM_LOGIN_PAGE;
                }
            else
                {
                return ExternalSecurity.USE_MSTR_DEFAULT_LOGIN;
                }
        
            }
  • Explanation: Override the getCustomLoginURL method so that it returns a URL that points to the custom login page. (The custom login page used in the corresponding scenario is called DiffLoginPagesCustLoginPage.jsp.):

    Copy
      /**
       * Return the URL of the custom login page.
       */
      public String getCustomLoginURL(String originalURL, String desiredServer, int desiredPort, String desiredProject) {
     
        /* The custom login page should have a login form where user can input login credentials.
         * After user submit the login form, the custom login page should create MicroStrategy Web IServer Session,
         * redirect to MicroStrategy page and have the session manager state in the URL using "usrSmgr" parameter.
         */
         return "http://localhost:8080/MicroStrategy/_custom/jsp/DiffLoginPagesCustLoginPage.jsp";
               }
     
      }

Custom login page  (called  DiffLoginPagesCustLoginPage.jspin the corresponding scenario)

A generic explanation of how to create the custom login page required to perform this customization is provided below. The code is explained in sections, with the explanation preceding each section of code.

  • Explanation: Import com.microstrategy.web.objects.:

    Copy
    <%@ page import="java.util.*, com.microstrategy.web.objects.*, com.microstrategy.web.objects.admin.users.*, com.microstrategy.webapi.*" %>
    <html>
    <%
  • Explanation: Create and instantiate a variable to represent the URL of the start page. This URL must point to a folder. To do this, you must set the evt (event) parameter in the URL to "2001", the event ID that opens a folder.:

    Copy
      //This url points to your MicroStrategy Web's desktop page.
      String mstrDesktopURL="http://localhost:8080/MicroStrategy/servlet/mstrWeb?evt=2001";
  • Explanation: Create and instantiate variables for the error message and the session state.:

    Copy
      String errorMsg = "";
      String sessionState="";
  • Explanation: Create and instantiate variables that represent the information collected from the custom login page and used to create an Intelligence Server session. Each parameter is read from the incoming request object. These user parameters will be used to build the Intelligence Server session.:

    Copy
      if("CustomLogin".equals(request.getParameter("CustomLogin"))) {
     
      //If the request comes from the custom login form, create session.
          String server = request.getParameter("Server");
          String project = request.getParameter("Project");
          String uid = request.getParameter("Uid");
          String pwd = request.getParameter("Pwd");
  • Explanation: Create an Intelligence Server session object. A WebObjectsFactory can be used to create other types of web objects, but in this case it is used to create an Intelligence Server session object that will be populated below.:

    Copy
          WebObjectsFactory lFactory = WebObjectsFactory.getInstance();
          WebIServerSession lISS = lFactory.getIServerSession();
  • Explanation: Set the user parameters that were read above onto the newly created Intelligence Server session. For exception handling purposes, these actions are wrapped in a try-catch block.:

    Copy
          try {
                lISS.setServerName(server);
                lISS.setProjectName(project);
                lISS.setLogin(uid);
                lISS.setPassword(pwd);
  • Explanation: Create the Intelligence Server session in standard authentication mode (MicroStrategy login and password) and save the minimal session state.:

    Copy
                //standard authentication
                lISS.setAuthMode(1);
                lISS.getSessionID();
                //save the minimal session state
                sessionState=lISS.saveState(0);
  • Explanation: Once the session has been created, you get the WebUser from it.  The WebUser is the user for whom the session was just created.  From the WebUser you get the list of parents for this user, which includes the list of groups to which this user belongs. :

    Sincegroups can be nested, to fully enumerate every group to which this user belongs, you would need to recursively go up the tree of parents.  However, to keep this sample simple, we have not done that here.

    Copy
                WebObjectInfo lUserOI = lISS.getUserInfo();
                WebUser lUser = (WebUser) lUserOI;
                WebUserList lParents = lUser.getParents();
              }
  • Explanation: A simple bit of error handling rounds out the try-catch block.  :

    A real application would handle errors more intelligently.

    Copy
            catch(WebObjectsException e)
              {
              errorMsg = e.getMessage();
              }
            }
  • Explanation: Finally, add code to show the login form if the request is not coming from the custom login form or there is error during creating session.:

    Copy
      if (!"CustomLogin".equals(request.getParameter("CustomLogin")) || !"".equals(errorMsg))
        {
        //If the request is not coming from the custom login form, or there is error during creating session, show the login form.
    %>
            <body>
            <h3>My Custom Login Form </h3>
            <h4><%=errorMsg%></h4></br>
            <form action="" id="loginForm" name="loginForm" method="post">
            <input type="hidden" name="CustomLogin" value="CustomLogin" />
            <label for="Server">Server name:</label> <input value="" type="text" class="txt" name="Server" id="Server"/><br/>
            <label for="Project">Project name:</label> <input value="" type="text" class="txt" name="Project" id="Project"/><br/>
            <label for="Uid">User name:</label> <input value="" type="text" class="txt" name="Uid" id="Uid"/><br/>
            <label for="Pwd">Password:</label> <input type="password" class="txt" name="Pwd" id="Pwd"/>
            <input value="1" type="hidden" name="ConnMode" id="ConnMode"/> <br>
            <input value="Login" type="submit" class="btn" name="3054" id="3054"/>
            </form>
            </body>
    <%
            }
          else
            {
            //If the session is created successfully.
    %>
            <body  onload="submitform()">
     
            <%-- hidden form --%>
            <form name='loginForm' action='<%=mstrDesktopURL%>' method='post' >
     
                <input type='hidden' name='usrSmgr' value='<%=sessionState%>' >
            </form>
     
            <%-- the JavaScript does the submit action on the hidden login form--%>
            <SCRIPT language="JavaScript">
            function submitform()
              {
                document.loginForm.submit();
              }
            </SCRIPT>
            </body>
    <%
            }
    %>
    </html>