Skip to content

Creating Remote Content And Authenticating Users

Brent Moberly edited this page Jan 12, 2015 · 1 revision

Overview

This tutorial will guide you through the process of developing and deploying your base, initial remote content file.

Requirements

In order to complete this tutorial, you will need the following:

  • A web-server to host your content files
  • An operational InCert server
  • An xml or text editor

Setup

This tutorial assumes that you have created the tutorial, Customizing the engine and setting its defaults, and have a version of the engine that will start and attempt to contact your web-server.

If you have not already, you will need to edit your version of init.xml to point to your remote content directory. To do this, edit the following block in your init.xml:

<WebServices.SetEndpointUrlForFunction>
  <Properties>
    <Function>GetContent</Function>
    <Url>https://certdev0.incommontest.org/incommon/windows/content/</Url>
  </Properties>
</WebServices.SetEndpointUrlForFunction>  

The engine uses simple HTTP GET requests to acquire its content files. This means that you can use a web-browser to view your content files and test your web-server. For example, click here to view InCert's current remote initial tasklist.

Once you have edited init.xml, repackage it into settings.cab, and sign and place settings.cab in your working engine folder. Again, see the tutorial, Customizing the engine and setting its defaults, for detailed instructions.

A Note On Security

Before we get into the tutorial proper, there are two things to keep in mind:

  1. the engine can handle HTTPS requests, and we recommend that you host its content files on an HTTPS- secured site. This prevents man-in-the-middle attacks, etc.

  2. by design, all of the engine's content files are publicly accessible. It's not a good idea to store secret information in your content files, and you shouldn't need to.

Creating tasklist.xml

After the engine initializes successfully, it downloads "tasklist.xml" from your content site. Here, the name "tasklist.xml" is a bit misleading, as this file will usually contain more than a single list of tasks. Tasklist.xml is essentially the remote equivalent of init.xml, inasmuch as it loads other remote content files and, generally, contains the engine's basic remote logic.

To create tasklist.xml

  1. Create a new sub-directory in your working directory called "Content."

content folder

This directory will contain local versions of your remote content files.

  1. Create a new file inside your content directory called tasklist.xml. The content of this file should be as follows:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Branches>
    <RoleBranch name="main" role="Remote" roleMode="Normal">
    </RoleBranch>
  </Branches>
</Content>

After the engine acquires and parses tasklist.xml from your content endpoint, it will execute the role-branch for the role "remote" and for the normal role-mode.

Role-modes are an advanced topic, but for now, the "main" role-branch of our tasklist.xml file is the first task-branch that the engine will execute. This, essentially, starts the engine proper.

  1. The first thing that we'll want to do is to deactivate the engine's splash-screen dialog. To do this, modify tasklist.xml to the following:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Branches>
    <RoleBranch name="main" role="Remote" roleMode="Normal">
      <UserInterface.StopMessageTimer>
        <Properties>
          <SettingKey>Splash screen progress text</SettingKey>
        </Properties>
      </UserInterface.StopMessageTimer>
      <UserInterface.HideDialog>
        <Properties>
          <Dialog>Splash screen dialog</Dialog>
        </Properties>
      </UserInterface.HideDialog>
    </RoleBranch>
  </Branches>
</Content>

Here, UserInterface.StopMessageTimer tells the engine to stop animating the message timer entitled Splash screen progress text, and UserInterface.HideDialog tells the engine to hide the dialog named Splash screen dialog. Both Splash screen dialog and Splash screen progress text are defined by default. But, this is another advanced topic.

  1. Upload tasklist.xml to your web-server. It should live in your remote content directory.

  2. In your engine folder, start your engine by running "elevator.exe." If everything is in order, your engine should start, display the splash screen, and then exit.

Here, we're using "elevator.exe" instead of "engine.exe" to start the engine. In normal mode, the engine expects to be run with elevated, administrative privileges. If not, it will prompt the user to elevate. Elevator.exe just prompts the user to start the engine elevated.

Yes, it is possible to run the engine in non-elevated mode. We'll cover this later, though.

Displaying an Authentication Dialog

One of the first things that we're going to want to do is to prompt users to authenticate against our web-service. To do this, we'll need to create and display an authentication dialog.

  1. Create a new xml file in your local content directory called "banners.xml." The content of this file should be as follows:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Banners>
  </Banners>
</Content>

This file will hold the xml definitions for our custom user-interface components. It's entirely possible to include Banners content in tasklist.xml, but we like to keep things in separate files. Otherwise, tasklist.xml can grow so long that it becomes difficult to edit.

  1. Add a SimpleBanner named LoginBanner to banners.xml:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Banners>
    <SimpleBanner name="LoginBanner" height="550" width="500">
      <Content>
        <SimpleParagraph margin="0,36,0,36" fontSize="24" alignment="Center">
          <Content>
            <DirectTextContent>!ApplicationTitle! Login</DirectTextContent>
          </Content>
        </SimpleParagraph>
      </Content>
      <Buttons>
        <ResultButton>
          <Target>NextButton</Target>
          <Text>Login</Text>
          <IsDefaultButton>true</IsDefaultButton>
          <Result>ControlResults.NextResult</Result>
        </ResultButton>
        <DisabledButton>
          <Target>BackButton</Target>
          <Text>Back</Text>
        </DisabledButton>
        <UrlButton>
          <Target>HelpButton</Target>
          <Text>Help</Text>
          <Value>https://certdev0.incommontest.org/incommon/index.html</Value>
        </UrlButton>
      </Buttons>
    </SimpleBanner>
  </Banners>
</Content>

Here, we're defining a banner that will be 550 pixels wide and 500 pixels high. Our banner will have a title, and next, back, and help buttons.

  1. Tell the engine to retrieve and parse banners.xml. To do this, modify tasklist.xml as follows:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Branches>
    <RoleBranch name="main" role="Remote" roleMode="Normal">
      <Control.GetContentFromEndpoint>
        <Properties>
          <ContentName>banners.xml</ContentName>
        </Properties>
      </Control.GetContentFromEndpoint>      
      <UserInterface.StopMessageTimer>
        <Properties>
          <SettingKey>Splash screen progress text</SettingKey>
       </Properties>
     </UserInterface.StopMessageTimer>
     <UserInterface.HideDialog>
       <Properties>
         <Dialog>Splash screen dialog</Dialog>
       </Properties>
     </UserInterface.HideDialog>
    </RoleBranch>
  </Branches>
</Content>

Here, Control.GetContentFromEndpoint instructs the engine to import and parse additional content files. We have placed it before the xml blocks that hide the splash dialog because we want to show the splash dialog until all of our content files have been processed.

  1. Tell the engine to display our login banner by adding a UserInterface.ShowBorderedBannerModal block to tasklist.xml:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Branches>
    <RoleBranch name="main" role="Remote" roleMode="Normal">
      <Control.GetContentFromEndpoint>
        <Properties>
          <ContentName>banners.xml</ContentName>
        </Properties>
      </Control.GetContentFromEndpoint>      
      <UserInterface.StopMessageTimer>
        <Properties>
          <SettingKey>Splash screen progress text</SettingKey>
       </Properties>
     </UserInterface.StopMessageTimer>
     <UserInterface.HideDialog>
       <Properties>
         <Dialog>Splash screen dialog</Dialog>
       </Properties>
     </UserInterface.HideDialog>
     <UserInterface.ShowBorderedBannerModal>
       <Properties>
         <Dialog>Main dialog</Dialog>
         <Banner>LoginBanner</Banner>
       </Properties>
      </UserInterface.ShowBorderedBannerModal>
    </RoleBranch>
  </Branches>
</Content>
  1. Upload tasklist.xml and banners.xml to your content server.

  2. Double-click elevator.exe in your working folder to start the engine. If everything is working, the engine should start, show its splash screen, and display its login dialog.

logon dialog with fields

Clicking Help should open a web-browser to the InCert provisioning api page and clicking Next should close the dialog and exit the engine. Back should be disabled.

Authenticating the User

Now that we have an authentication dialog, we actually need to authenticate the user. To do this, we'll add input fields to our authentication dialog and then use the content of these fields to authenticate to the server via our web-service authentication endpoint.

  1. Modify LoginBanner in banners.xml as follows:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Banners>
    <SimpleBanner name="LoginBanner" height="550" width="500">
      <Content>
        <SimpleParagraph margin="0,36,0,36" fontSize="24" alignment="Center">
          <Content>
             <DirectTextContent>!ApplicationTitle! Login</DirectTextContent>
          </Content>
       </SimpleParagraph>
       <SimpleParagraph>
         <Content>
           <DirectTextContent>Username:</DirectTextContent>
         </Content>
       </SimpleParagraph>
       <SimpleInputField settingKey="username" controlKey="username"/>
       <SimpleParagraph margin="0,8,0,0">
         <Content>
           <DirectTextContent>Passphrase:</DirectTextContent>
         </Content>
       </SimpleParagraph>
       <PasswordInputField settingKey="passphrase" controlKey="passphrase"/>
       <SimpleParagraph margin="0,8,0,0">
         <Content>
           <DirectTextContent>Credential 2:</DirectTextContent>
         </Content>
       </SimpleParagraph>
       <SimpleInputField settingKey="credential2"/>
       <SimpleParagraph margin="0,8,0,0">
         <Content>
           <DirectTextContent>Credential 3:</DirectTextContent>
         </Content>
       </SimpleParagraph>
       <SimpleInputField settingKey="credential3"/>
       <SimpleParagraph margin="0,8,0,0">
          <Content>
            <DirectTextContent>Credential 4:</DirectTextContent>
          </Content>
        </SimpleParagraph>
        <SimpleInputField settingKey="credential4"/>
        <SimpleParagraph controlKey="Instructions" margin="0,12,0,0">
          <Content>
           <DirectTextContent>
             Please provide your network credentials and click Login to continue.
           </DirectTextContent>
          </Content>
        </SimpleParagraph>
      </Content>
      <Buttons>
        <ResultButton>
          <Target>NextButton</Target>
          <Text>Login</Text>
          <IsDefaultButton>true</IsDefaultButton>
          <Result>ControlResults.NextResult</Result>
        </ResultButton>
        <DisabledButton>
          <Target>BackButton</Target>
          <Text>Back</Text>
        </DisabledButton>
        <UrlButton>
          <Target>HelpButton</Target>
          <Text>Help</Text>
          <Value>https://certdev0.incommontest.org/incommon/index.html</Value>
        </UrlButton>
      </Buttons>
    </SimpleBanner>
  </Banners>
</Content>

We've added a lot of xml here. Essentially, what we've done is add five fields (with labels) to our dialog and some instructions text. Four of the fields are standard input fields, while one of the fields in masked, or password, input field.

  1. Upload banners.xml to your content server and start your engine by clicking elevator.exe. If everything worked, your login banner should look like this:

logon dialog with fields

Note that SimpleInputField and PasswordInputField both take a settingKey attribute. When users input content into one of these fields, that content is persisted in the engine's temporary settings store and associated with the key specified in the field's settingKey attribute. This allows the engine to reference these values at a later time.

  1. In tasklist.xml, add an Authentication.AuthenticateUser block to the end of your main role-branch:
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://incert.incommon.org/schemas ../Schemas/tasklist.xsd">
  <Branches>
    <RoleBranch name="main" role="Remote" roleMode="Normal">
      <Control.GetContentFromEndpoint>
        <Properties>
          <ContentName>banners.xml</ContentName>
        </Properties>
      </Control.GetContentFromEndpoint>      
      <UserInterface.StopMessageTimer>
        <Properties>
          <SettingKey>Splash screen progress text</SettingKey>
       </Properties>
     </UserInterface.StopMessageTimer>
     <UserInterface.HideDialog>
       <Properties>
         <Dialog>Splash screen dialog</Dialog>
       </Properties>
     </UserInterface.HideDialog>
     <UserInterface.ShowBorderedBannerModal>
       <Properties>
         <Dialog>Main dialog</Dialog>
         <Banner>LoginBanner</Banner>
       </Properties>
      </UserInterface.ShowBorderedBannerModal>
      <Authentication.AuthenticateUser>
        <Properties>
          <UsernameKey>username</UsernameKey>
          <PassphraseKey>passphrase</PassphraseKey>
          <Credential2Key>credential2</Credential2Key>
          <Credential3Key>credential3</Credential3Key>
          <Credential4Key>credential4</Credential4Key>
          <CertificateProvider>incommontest.org</CertificateProvider>
        </Properties>
      </Authentication.AuthenticateUser>
    </RoleBranch>
  </Branches>
</Content>

If you consult the InCert Provisioning Tools API Examples, you'll see that properties of Authentication.AuthenticateUser correspond to those required by the authentication web-service endpoint.

Here, Authentication.AuthenticateUser retrieves the values persisted in the engine's temporary settings store and passes them up to the authentication web-service endpoint. Note that the values of the various "key" properties correspond to those assigned to the settingKey attributes of the fields on our login dialog.

  1. Upload tasklist.xml and banners.xml to your content server and run the engine again. If everything worked properly, clicking Next after providing the correct credentials will cause the engine to exit.

If you provide the wrong credentials, you should see this error dialog:

Authentication error

Conclusion

Our new authentication dialog works, but it leaves a lot to be desired. It allows users to click Next if fields are empty, and it does nothing to signal to the user that authentication is in progress. We'll work on this in the next tutorial....