Thursday, October 2, 2008

PENS authentication

I've written before about how to use a PENS-conformant authoring tool or LCMS with EKP. However, in that post I didn't fully explain the intricacies of how EKP handles authentication of PENS requests.

EKP actually provides two PENS endpoints, which differ only in how they handle authentication. Assuming your installation uses the default /ekp/ path prefix, the endpoint URLs are as follows.

/ekp/pens
/ekp/servlet/ekp/pens

The first of these endpoints handles authentication exactly as described in the PENS specification. That is, the PENS request is expected to include parameters named system-user-id and system-password, the values of which should correspond with, respectively, the user ID and password of an EKP account with permission to create courses. (In fact, this endpoint will also accept credentials supplied as an HTTP basic authentication header. This is allowed primarily for consistency with other EKP web services. However, the request parameters always take precedence when supplied.)

The second endpoint ignores the PENS authentication request parameters and HTTP basic authentication headers, and instead uses EKP's standard login sessions for authentication. While this is strictly outside the scope of the PENS specification, it is convenient in situations where the PENS request originates directly from a browser. Since the user is likely to have already logged into EKP at the time at which the PENS request is sent, this approach avoids the need for the user to re-enter his or her credentials every he or she initiates the PENS publishing process.

Monday, September 1, 2008

User accounts and user statuses

Every user account in EKP has a Current Status field which, as of EKP 5.5, can take one of seven possible values. Herewith, a list of the possible values, and an explanation of the usage of each.

Active
The account is available for login.
Suspended
The account is not currently available for login, but is expected to be reactivated in the future. An account can be marked as Suspended by an administrator, or automatically as a result of too many failed logins.
Account Closed
The account is not available for login, and is not expected to be reactivated in the future. However, the account will still be viewable using review and administrative functions.
Logically Deleted
The account is not available for login, and is not expected to be reactivated in the future. Moreover, the account will be hidden in most parts of the system aside from the User Editor.
Self registration user pend for approval
The account was created by a user self-registering with the system. It is awaiting approval and activation by an administrator.
Locked
The account is not currently available for login, but might be reactivated in the future. Similar to Suspended. If specified under System Configuration, accounts are automatically marked as Locked after a period of inactivity.
User Account/Records Migrated
Used to indicate that records that were previously associated with this account have been migrated to a different account. The account is effectively obsolete, but has not yet been deleted.

[This post was updated on October 28, 2010 to remove obsolete licensing information.]

Wednesday, July 9, 2008

Desktop publishing tools and PENS

I've written before about how PENS can be used to enable one-click publishing from a publishing system (authoring tool or LCMS). Herewith, some notes on using PENS with desktop, as opposed to web-based, tools.

PENS requires that, when a publishing system sends a request to the LMS to “collect” a content package, it supplies a URL (typically using one of http, https or ftp for the URL scheme) from which the package can be collected. If the publishing system is web-based, then this URL will typically refer back to the publishing system itself.

For a desktop publishing system, this requirement effectively means that there needs to be a server, separate from the desktop software, to which the content can be uploaded prior to being collected by the LMS. Typically this will be an FTP server, although it could in principle be a web server.

Ideally, the desktop software will enable the user to configure details of this FTP server (including host, user name and password) in addition to the LMS details. When a course is published, the software should perform the following actions:

  • package the content into a zip file;
  • upload the content package to the FTP server using the configured host, user name and password; and
  • send a PENS request to the LMS instructing it to collect the content package from the FTP server.

In principle, it would be possible to manually upload the content package to the FTP server if the desktop software does not do this automatically. In practice, though, this really defeats the purpose of using PENS, since it would be simpler to create a SCORM or AICC content package on the desktop machine, and then upload the package directly to the LMS.

Another theoretical possibility would be to run a web or FTP server on the desktop machine itself. However, this would require that the desktop machine has a stable IP address and/or host name that the LMS can call back to, and that HTTP or FTP requests to the desktop machine are not blocked by hardware or software firewalls. In other words, it's almost guaranteed not to work in practice.

In summary, a desktop publishing system can theoretically “support” PENS without also supporting the automatic FTP upload step. However, without this automatic FTP upload, PENS is unlikely to provide any practical benefit.

Sun Java Plug-in bug and SCORM communication

A few users have encountered the following issue that affects tracking of SCORM courses on a small number of EKP sites.

Symptoms: SCORM courses fail to communicate with EKP, and one or more messages like the one below appear in the browser's Java console.

java.security.AccessControlException: access denied (java.net.SocketPermission www.example.com:80 connect,resolve)

Analysis: This issue is caused by a bug in certain versions of Sun's Java Plug-in. The bug was introduced in Java 6 Update 3, and is fixed in Java 6 Update 10. It affects Firefox and Safari; Internet Explorer is not affected.

Note that this problem does not affect all sites. It appears to affect a small proportion of sites, and is related to the site's DNS configuration.

Solution: Users who encounter the problem described above can apply one of the following solutions.

  • Ensure that your users are using a version of the Sun Java Plug-in that is not affected by this problem. Users who currently have Java 6 Update 3 or above can upgrade to Java 6 Update 10. (Note that, as of 9 July 2008, Update 10 is flagged as “beta.” However, it is the first version offered on the downloads page.)
  • Another solution that appears to be effective is to ensure that each EKP domain (e.g. ekp.example.com) is mapped (via DNS) to a unique IP address. That is, where multiple EKP instances are located on a single server, ensure that each instance on the server is associated with a different IP address.

Sunday, June 15, 2008

When do I need to use the Content Server Configuration settings in EKP Gold?

EKP Gold includes a Content Server Configuration page (under Manage > System Administration Manager > System Settings). However, it's not always necessary to explicitly configure a content server in order to enable learners to launch courses from servers other than the EKP server. Herewith, clarification of when it's necessary to explicitly configure a content server, and when it isn't.

Content Server Configuration menu item

EKP's content server configuration settings are designed to help you deliver courses to groups of learners whose connections to the main EKP server have limited bandwidth. You can upload the same course content to multiple content servers, and ensure that, when a learner launches a course, the course content will be delivered to the learner from a server that provides optimal delivery speeds. (The choice of server can be based on either the learner's identity or their network location.)

For example, suppose you need to deliver courses to employees located in your brand new lunar office. Since bandwidth between the moon and Earth is limited, you would like to ensure the course content is delivered to your lunar employees from a dedicated lunar content server, while Earth-based employees will continue to receive course content from your Earth-based server. You can use EKP's content server configuration to ensure that lunar employees receive course content from moon.example.com, while terrestrial employees receive the same content from earth.example.com.

However, there are other reasons besides bandwidth why you might want course content to reside on a different server from EKP. For example, the course content might require a server-side scripting language that is not available on the EKP server. Or the courses might be provided by a vendor that hosts the content themselves instead of providing it as files to be uploaded to an LMS server (which can be extremely convenient if the content is updated frequently). In these cases, although the content for a particular course will be delivered from a content server separate from the main EKP server, it will always be delivered from the same server regardless of the learner's identity and network location.

If the content of any particular course should always be delivered from the same server, even if it is not the main EKP server, then it's not necessary to explicitly configure any content servers, and it's not necessary to be running EKP Gold. In this case, it's only necessary to ensure that the relevant launch URLs accurately reflect the location of the course content (which might require that they be specified as absolute, rather than relative, URLs), and this will work just fine on EKP Silver or EKP Bronze. Note that it's still possible to import the EKP course catalog entries from SCORM or AICC content packages even if the course content will not reside on the EKP server; however, in this case the packages will typically contain only course description files (i.e. imsmanifest.xml and related files in the case of SCORM-conformant courses, or AICC course structure files in the case of AICC-conformant courses), and not the actual course content files. Note also that you might still need to work around cross-site scripting issues—however, it's generally more straightforward to do this by setting up a reverse proxy on the EKP server rather than by explicitly configuring content servers in EKP.

(To be really precise, we should state that content server configuration is required only if the host portion of any course content URLs needs to change based on the learner's identity or location—for example, http://earth.example.com/path/to/content versus http://moon.example.com/path/to/content. This is not quite the same as stating that the courses need to be launched from different servers, since it is possible to map a single host name to multiple physical servers—for example, the single host name earth.example.com might be mapped to multiple physical servers. However, this difference is unlikely to matter in practice unless special content distribution technology is being used.)

Saturday, June 7, 2008

How can I change the size of the navigation frames for a course with multiple SCOs or AUs?

When you launch a SCORM course with multiple shareable content objects (SCOs), an AICC with multiple assignable units (AUs), or a course created using the Courseware Manager with multiple lessons, EKP provides one or more frames containing navigation controls that the learners can use to navigate between the SCOs, AUs or lessons of the course.

If you are using EKP Gold or EKP Silver, you can change the size of these frames by creating a custom courseware template, provided that you have the appropriate administrative privileges. The steps are as follows.

  • Create a courseware template package. You can use the files under nd/fresco/template/course/default as a guide. Copy the files to a new folder, edit default.css as required, then package the files as a zip file, ensuring that default.css is in the root of the package. (Note that you do not need to edit default.css to change the size of the navigation frames, but you can change the fonts and colors used for the navigation controls.)
  • Go to Manage > Courseware Manager > Courseware Template Editor, and click the Create button.
    Create button
  • In the new window, enter a name for the template, then click the Browse... button and select the courseware template package (zip file) you created.
    Name and zip file selection fields
  • On the next page, click the top frame in the image.
    Top frame image
  • In the Top Frame window, enter the desired height for the top frame. You can specify the height as a percentage of the total window height or as an absolute number of pixels.
    Height field
  • Set the width of the left frame by clicking the left frame in the image.
    Left frame image
  • Click Update to save the courseware template settings.

You can configure a course with multiple SCOs, AUs or lessons to use your custom template by opening the course in the Catalog Editor, clicking Navigation Setup in the left frame, selecting your custom template from the Template drop-down list, then clicking the Save button in the top frame.

Courseware Template Selector

Note that EKP needs to provide navigation controls for a course with multiple SCOs, AUs or lessons in order to ensure correct tracking, so you cannot remove the navigation frames. For a more detailed, see my earlier post.

Monday, May 26, 2008

Code samples: invoking APIs using C#

I've previously posted sample code that demonstrates how to invoke EKP's APIs using Java and Visual Basic. Herewith, equivalent code using C#.

As with modern Visual Basic, C# is a .NET-based language. It's therefore fairly straightforward to translate our previous Visual Basic sample code into C#. As with the Visual Basic code, we will use an instance of System.Net.WebClient to make the API calls.

System.Net.WebClient client = new System.Net.WebClient();

Again, we need to set the credentials that WebClient will use for the HTTP basic authentication process. We must set the user name to a non-empty value to ensure that WebClient sends the authentication header, but the exact value doesn't matter since EKP ignores it. The password must match the value of the authentication.key property configured in the file WEB-INF/conf/ekp.properties.

String userName = "dummy";
String key = "mysecretkey";
client.Credentials = new System.Net.NetworkCredential(userName, key);

To create a user account, we send an HTTP POST request to /ekp/contentHandler/usersCsv, including CSV-formatted data in the body of the request.

String data1 = "Action,UserID,Password,FamilyName,GivenName\r\n"
             + "A,joestudent,dummypass,Student,Joe\r\n";
client.UploadString("https://ekp.example.com/ekp/contentHandler/usersCsv",
                    data1);

Similarly, we can enroll the user in a course with ID Derivatives_101 by sending an HTTP POST request to /ekp/enrollmentHandler, again including appropriately-formatted CSV data in the body of the request.

String data2 = "USERID,LEARNINGID\r\n"
             + "joestudent,Derivatives_101\r\n";
client.UploadString("https://ekp.example.com/ekp/enrollmentHandler", data2);

Sunday, May 25, 2008

Code samples: invoking APIs using Visual Basic

I've previously posted sample Java code that demonstrates how to invoke EKP's APIs. Herewith, equivalent code using Visual Basic .NET.

The .NET platform provides a couple of classes for sending HTTP requests, specifically System.Net.HttpWebRequest and System.Net.WebClient. Either will do the job. However, WebClient is a little simpler to work with, so that's what we'll use.

Dim client As Net.WebClient = New Net.WebClient()

API requests must include an HTTP basic authentication header. Fortunately, both WebClient and HttpWebRequest have built-in support for HTTP basic authentication, so this is straightforward. The user name is ignored by EKP; however, we must set the user name to a non-empty value, otherwise WebClient won't send the authentication header. The password must match the value of the authentication.key property configured in the file WEB-INF/conf/ekp.properties.

Dim userName As String = "dummy"    ' any non-empty value is okay
Dim password As String = "mysecretkey"
client.Credentials = New Net.NetworkCredential(userName, password)

To create a user account, we send an HTTP POST request to /ekp/contentHandler/usersCsv, including CSV-formatted data in the body of the request.

Dim data1 As String _
        = "Action,UserID,Password,FamilyName,GivenName" & ControlChars.CrLf _
        & "A,joestudent,dummypass,Student,Joe" & ControlChars.CrLf
client.UploadString("https://ekp.example.com/ekp/contentHandler/usersCsv", _
                    data1)

Similarly, we can enroll the user in a course with ID Derivatives_101 by sending an HTTP POST request to /ekp/enrollmentHandler, again including appropriately-formatted CSV data in the body of the request.

Dim data2 As String = "USERID,LEARNINGID" & ControlChars.CrLf _
                    & "joestudent,Derivatives_101" & ControlChars.CrLf
client.UploadString("https://ekp.example.com/ekp/enrollmentHandler", data2)

Saturday, May 17, 2008

Which catalog fields can EKP extract from the metadata in a SCORM package?

When you import a SCORM or IMS content package, EKP scans the file named imsmanifest.xml that every such package must contain, and extracts certain key information including: the course identifier; the title of the course; and information about the structure of the course including URLs and additional parameters used to launch the individual SCOs and assets.

In addition to this essential information, the package may also contain metadata in the form of a Learning Object Metadata (LOM) XML instance (either embedded in imsmanifest.xml itself, or else in a separate file referenced from imsmanifest.xml). If present, EKP can extract from this metadata any or all of the catalog fields listed below.

  • Description
  • Vendor
  • Duration Comments
  • Objectives
  • Training Hours

Shown below is a minimal LOM XML from which EKP can extract all of the additional catalog fields listed above. The relevant field values are shown in bold text. This example follows IMS LOM as used in SCORM 1.2 packages; however, the same information could be extracted from an IEEE LOM as used in SCORM 2004, and the differences would be minor.

(Note that this is a minimal XML instance from which EKP can extract the values mentioned above. The LOM XML schema denotes as mandatory some elements that are not actually required by EKP, hence this example is not actually valid against the schema, and the SCORM conformance test suite will report it as invalid.)

<lom xmlns="http://www.imsglobal.org/xsd/imsmd_rootv1p2p1">
   <general>
      <description>
         <langstring>Description</langstring>
      </description>
   </general>
   <lifecycle>
      <contribute>
         <centity>
            <vcard>ORG:Vendor</vcard>
         </centity>
      </contribute>
   </lifecycle>
   <educational>
      <typicallearningtime>
         <datetime>02:30:00</datetime>
         <description>
            <langstring>Duration Comments</langstring>
         </description>
      </typicallearningtime>
   </educational>
   <classification>
      <purpose>
        <value>
           <langstring>Educational Objective</langstring>
        </value>
      </purpose>
      <description>
         <langstring>Objective #1</langstring>
      </description>
   </classification>
   <classification>
      <purpose>
        <value>
           <langstring>Educational Objective</langstring>
        </value>
      </purpose>
      <description>
         <langstring>Objective #2</langstring>
      </description>
   </classification>
   <classification>
      <purpose>
        <value>
           <langstring>Educational Objective</langstring>
        </value>
      </purpose>
      <description>
         <langstring>Objective #3</langstring>
      </description>
   </classification>
</lom>

Tuesday, March 25, 2008

Pragmatic API design

In a comment on a previous post, Carfield Yim suggests an alternative style for API requests. We could dub this the URL-encoded style, since the content type associated with the request format is application/x-www-form-urlencoded. (Carfield's example involves updating a user's name, so the hypothetical service ought to require that the request be submitted using HTTP POST method rather than GET, since the action is unsafe.)

There is eternal debate in the software and web communities on the question of what APIs should look like, involving an acronym soup of terms such as SOAP, REST, SOA, POX and ROA. Without invoking too many buzzwords, we can observe that the following are both desirable properties of real-world APIs.

  1. Support for invoking an operation, and viewing the response, directly in a browser. Typically the requests would need to be submitted using an HTML form. This can be very useful to a developer trying to make use of the API, since it becomes incredibly easy to test its behavior. Learning by experiment is often easier and more effective than reading a specification.
  2. Reuse of existing data formats. For example, one of the examples in the original post was concerned with creating a user account in EKP. The body of the request message contained CSV data in the format EKP expects for files uploaded using the User Data Loader. Hence, if an organization has already written code to generate data in that format (extracted from their HR system for example), it needs relatively little work to switch between either generating files for manual upload, or submitting the data directly using the API. On the other hand, the application/x-www-form-urlencoded content type isn't normally used outside of HTTP requests.

(In passing, it's worth noting that SOAP does not satisfy either of these requirements particularly well. It fails completely with the first. As for the second, it's reasonably easy to reuse an existing format if it is XML-based and literal encoding is used rather than SOAP encoding. On the other hand, using a format that is not XML-based—because it predates XML for example—typically requires sending the data as some kind of SOAP attachment, which raises a whole other set of issues.)

In some cases, support for batch operations might also be a requirement. For example, if I need to update 1,000 user records, this will be considerably more efficient if the data can be sent in a single request. If 1,000 separate requests are required, then network latency will become a serious concern. (However, HTTP pipelining could help if supported.)

As I see it, the URL-encoded request style meets the first requirement (it supports invocation from a browser), but fails to meet the second (it fails to reuse an existing data format for the request) and third (it is not well suited to batch operations). On the other hand, the CSV request style described in the original post fails to meet the first requirement, but meets the second and third. This seems like a reasonable trade-off in this case. However, the URL-encoded style seems like a reasonable approach in cases where support for large batch updates isn't a critical requirement, and there isn't an existing data format that obviously matches the desired content of the request message.

Thursday, March 20, 2008

Code samples: invoking APIs using Java

Following on from my previous post, I thought it might be useful to post some sample code that demonstrates how to invoke EKP's APIs, in this case using Java.

Every API request must include an HTTP basic authentication header. If you are using Java's built-in HttpURLConnection class, you would need to construct and add this header manually. This is not hard, and the EKP APIs and Web Services Overview explains how to do it. However, it's even easier to use a library that supports HTTP basic authentication directly.

One such library is Jakarta Commons HttpClient. HttpClient is free, open source, and distributed under version 2.0 of the Apache License, meaning that it can be used with minimal obligations in software that is not itself open source. (Note that HttpClient has dependencies on both Commons Logging and Commons Codec, so you will also need both of those to run this sample code.)

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

We begin by creating an instance of HttpClient, which is straightforward.

HttpClient httpClient = new HttpClient();

We need to initialize the HttpClient object with the appropriate user name and password. The user name is ignored by EKP, so we simply use the empty string. The password must match the value of the authentication.key property configured in the file WEB-INF/conf/ekp.properties.

String userName = "";
String key = "mysecretkey";
httpClient.getParams().setAuthenticationPreemptive(true);
httpClient.getState().setCredentials(AuthScope.ANY,
        new UsernamePasswordCredentials(userName, key));

As described in the previous post, we can create a user account (here, joestudent) by sending an HTTP POST request to /ekp/contentHandler/usersCsv, and including CSV-formatted data in the body of the request.

PostMethod postMethod1 = new PostMethod(
        "https://ekp.example.com/ekp/contentHandler/usersCsv");
String content1 = "Action,UserID,Password,FamilyName,GivenName\r\n"
                + "A,joestudent,dummypass,Student,Joe\r\n";
postMethod1.setRequestEntity(new StringRequestEntity(content1,
        "text/plain", "UTF-8"));
httpClient.executeMethod(postMethod1);

Similarly, we can enroll joestudent in a course with ID Derivatives_101 by sending an HTTP POST request to /ekp/enrollmentHandler, again with appropriately-formatted CSV data in the body of the request.

PostMethod postMethod2 = new PostMethod(
        "https://ekp.example.com/ekp/enrollmentHandler");
String content2 = "USERID,LEARNINGID\r\n"
                + "joestudent,Derivatives_101\r\n";
postMethod2.setRequestEntity(new StringRequestEntity(content2,
        "text/plain", "UTF-8"));
httpClient.executeMethod(postMethod2);

API 101

We just finished a fairly intensive training session here in Hong Kong with a couple of partners. The subject was ostensibly our customization toolkit, but we also spent quite a bit of time discussing APIs and how EKP can be integrated with existing web sites, portals and applications. Every time we conduct these training sessions, this topic expands.

Here's an outline of what we covered, with links to the relevant documentation.

  1. The first step in seamlessly combining EKP functionality with an existing site is understanding how to implement web-based single sign-on.
  2. With a single sign-on mechanism in place, it's possible to have external pages link directly to specific pages in EKP, and, in particular, to launch courses directly from external pages. (See also: How can I link directly to a page in EKP without losing the navigation frames?)
  3. Data can be manipulated in, or extracted from, EKP using the APIs described in the EKP APIs and Web Services Overview. Examples:
    • To ensure that EKP has a user account for a specific user ID (as part of the single sign-on process for example), have the external site send a direct server-to-server HTTP POST request to /ekp/contentHandler/usersCsv, with CSV-formatted data (following the User Data Loader format) in the body of the request. Note that most of the columns are optional when the User Data Loader format is used, so the following is valid for example:
      Action,UserID,Password,FamilyName,GivenName
      A,joestudent,mypassword,Student,Joe
    • To ensure that a specific user is enrolled in a specific course (prior to launching the course for example), have the external site send a direct server-to-server HTTP POST request to /ekp/enrollmentHandler with CSV-formatted data in the body of the request. For example:
      USERID,LEARNINGID
      joestudent,Derivatives_101
    • To retrieve a complete training history, in XML format, for user joestudent (to display within an external page for example), have the external site send a direct server-to-server HTTP GET request to /ekp/contentGenerator/trainingHistoryXml?userId=joestudent.

Update: I posted Java code samples for creating a user account and enrolling a user in a course.

Update 2: Musings on the invocation style of the API operations discussed above, prompted by Carfield's comment.

Wednesday, March 19, 2008

NoSuchMethodError when upgrading to EKP 5.0

We've had a few reports of the following problem: when connecting to an EKP site that has been upgraded to EKP 5.0, a "Cannot connect to database" page is seen, and a message like the one below appears in the log file (WEB-INF/logs/ekp.log).

java.lang.NoSuchMethodError: javax.xml.parsers.DocumentBuilderFactory.getSchema()Ljavax/xml/validation/Schema;
 at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.<init>(DocumentBuilderImpl.java:110)
 at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl.newDocumentBuilder(DocumentBuilderFactoryImpl.java:101)
 at com.sun.msv.verifier.jaxp.DocumentBuilderFactoryImpl.newDocumentBuilder(DocumentBuilderFactoryImpl.java:145)

This appears to happen if EKP is running on an older version of Tomcat 4.1. Older versions of Tomcat 4.1 will override the XML parser libraries that are included in the Java runtime, and these libraries conflict with the versions included in J2SE 5.0, which EKP 5.0 requires.

The simplest solution is to delete the parser libraries that are included with Tomcat 4.1. These can be found in the common/endorsed/ directory under the Tomcat home directory. These libraries are not required when running under J2SE 5.0.

On Safari

I just sat down at my computer and was greeted with this.

Apple Software Update window with Safari 3.1

I have never installed Apple's Safari browser, but I do have iTunes and QuickTime. Apparently Apple is trying to leverage iTunes and QuickTime to push Safari to as many PCs as possible.

If this is at all successful, Safari's usage share could increase significantly.

Tuesday, March 18, 2008

Custom login pages

Most EKP sites will use a custom login page rather than the standard page that ships with EKP. This is done by creating a file named login.wm and placing it in the WEB-INF/conf/ directory. The contents of this page are essentially HTML, with some placeholders for dynamic content that use the Velocity Template Language (VTL).

The standard login page, which can be used as a guide, can be extracted from the file WEB-INF/lib/ekp.jar using a zip utility such as WinZip or WinRAR. The location of the page within the ekp.jar file is com/netdimen/tx/auth/login/login.wm for EKP 4.7 and above, or com/netdimen/tx/login/login.wm for EKP 4.6.

One important point that is easy to overlook is that the page should contain the code shown below immediately after the opening <form> tag of the login form.

  #if ($target != "")
  <input type="hidden" name="target" value="$target" />
  #end

This code will ensure that, if a user who is not logged in attempts to access a page that requires authentication (which would happen if the user's session had timed out, for example), EKP will "remember" which page the user was trying to access and forward the user to that page after prompting her to log in. If users are always forwarded to the default start page after logging in, even if they were prompted to log in while trying to access another page, it is most likely because the above code is missing from the login page template.

(Note that the default static index.html page simply redirects the user to the dynamic login page described above. We recommend leaving the index.html page as-is and simply creating a login.wm page as described above, to avoid duplicating the custom login page HTML code.)

If your EKP site is hosted by NetDimensions, these steps will normally be performed for you by our staff.

Sunday, March 16, 2008

Directory services and hosted EKP sites

Consider the following scenario, which is not uncommon. An organization wishes to make use of an EKP site that is hosted outside of their network. The organization has already implemented a directory service (Active Directory for example) that is most likely accessible via LDAP. Naturally, the organization would like their users to be able to access EKP using the usernames and passwords stored in the directory service. Below are three ways in which this could be accomplished.

  1. Usernames and passwords could be exported from the directory service (using a tool such as CSVDE for Active Directory for example) and imported into EKP. The import could be performed manually using EKP's CSV User Data Loader, or it could be automated using EKP's APIs or import scheduler. Users would log into EKP using EKP's standard login page.
  2. The EKP site could be configured to connect directly to the organization's directory service using LDAP to perform authentication. Again, users would log into EKP using EKP's standard login page.
  3. A login page could be created on a web server in the organization's DMZ that connects to the organization's directory service and implements an authentication service for EKP as described in this previous post.

The first approach has a few disadvantages.

  • It is not real-time. For example, a password change in the directory service will not take effect on the EKP site until the next time the usernames and passwords are synchronized.
  • For extra security, systems that support password-based authentication might store a cryptographic hash of a password, from which it is infeasible to recover the original password, instead of storing the original password. (In fact EKP does exactly this, which is why it is not possible to export passwords from EKP.) Thus, it might not be possible to export passwords from the directory service.
  • Even if it is technically possible to export passwords from the directory service, replicating passwords on a system outside of the organization's network might violate the organization's security policies.

The second approach avoids these problems. However, it does require that the organization's directory service be accessible from outside the organization's network, which often will not be the case. (This would of course be the preferred approach if the EKP site was hosted inside of the organization's network.)

The third approach has several advantages.

  • It is real-time. For example, when a password is changed in the directory service, the new password will immediately be effective for accessing EKP.
  • It does not require passwords to be exported from the directory service or replicated outside of the organization's network.
  • It does not require that the directory service be accessible outside of the organization's network via LDAP.
  • In cases where the organization already has a web site or portal that authenticates against the directory service, the authentication service for EKP can be combined with the existing site, thus providing single sign-on between the existing site and EKP.

This third approach should be the preferred approach in most cases where the EKP site is hosted outside of the organization's network.

Saturday, March 15, 2008

Specifications and copyright

IMS Global Learning Consortium: Today the IMS Global Learning Consortium (IMS GLC) announced plans to initiate a pilot project in the distribution of interoperability specifications under a form of Creative Commons license.

There's a murky relationship between technical interoperability specifications and standard copyright. Here's an example.

Every SCORM-conformant content package needs to contain a set of W3C XML Schema documents. Since SCORM content packaging is derived from the IMS Content Packaging specification, one of these required documents is an IMS Content Packaging schema document, which contains an unambiguous IMS GLC copyright notice.

Based on this, it seems one could make a reasonable case that every SCORM-conformant content package is a derivative work, and hence an infringement of IMS' copyright.

Adopting a framework such as Creative Commons seems like a sensible way forward.

Thursday, March 6, 2008

SCORM and AICC compared

GerryWaz: Anyone know of a good, dispassionate comparison of the two standards? Strengths and weaknesses of each?

In matters of technology, newer is frequently equated with better. However, while SCORM is the newer specification and is more widely supported, there are valid reasons for using courses and management systems based on the AICC specifications.

Below are some points to consider when deciding between AICC and SCORM. (We consider only SCORM 1.2 and SCORM 2004, since earlier versions of SCORM are effectively obsolete.)

Packaging and deployment
Thanks to SCORM's well-defined packaging model, deploying SCORM courses is often as simple as uploading a zip file. Historically, deploying AICC courses involved more steps due to the lack of a similar packaging model for these courses. In late 2006, AICC published a packaging specification for AICC courses. However, this is still not part of the core AICC specification, so neither AICC-conformant courses nor AICC-conformant LMSs are required to support it. (EKP supports AICC course packages.)
Ease of development
SCORM-conformant courses communicate with an LMS by calling methods of a JavaScript object called the API adapter. AICC-conformant courses communicate with an LMS by sending HTTP messages to the LMS, and interpretting the LMS's responses. (This communication method is known as the HTTP AICC CMI Protocol, or HACP.) Where courses are developed without the aid of specialized course authoring tools, it's usually considerably easier to implement SCORM communication than AICC communication. (However, most specialized course authoring tools shield the developer from these differences.)
Technical requirements
A conformant SCORM API adapter must implement complex rules for validating tracking data and reporting errors and, in the case of SCORM 2004, for evaluating and enforcing sequencing rules and processing navigation requests. Because of this complexity, many robust implementations use Java technology to implement the API adapter, meaning that Java must be available on the user's machine. (Both EKP and ADL's reference implementations use Java to implement the API adapter.) On the other hand, since AICC courses use direct HTTP-based communication, LMSs typically don't require Java to track AICC courses. (However, the courseware itself might still require Java.)
Cross-site scripting
Cross-site scripting occurs when content loaded from one web site in a browser attempts to read or manipulate content loaded from another web site in the same browser. In general, cross-site scripting presents a security risk, and browsers rightly restrict it in most cases. However, these restrictions can also interfere with tracking of courses where the courses reside on a different web site from the LMS. The problem is usually more serious for SCORM courses than for AICC courses. As described above, SCORM courses communicate with the LMS using JavaScript calls, and these are almost always blocked when the course and LMS reside on different sites. On the other hand, due to the nature of AICC communication, AICC courses have greater choice about the specific technology used to perform the communication, and different technologies enforce different policies regarding cross-site communicating. For example, an unsigned Java applet may not communicate with a site other than the one from which it was loaded, but a signed Java applet may do so if the user explicitly grants permission. Even without the use of browser plug-ins such as Java or Flash, an AICC course can implement course-to-LMS communication (but not LMS-to-course communication) simply by using standard HTML forms.
Sequencing
The AICC, SCORM 1.2 and SCORM 2004 specifications all provide sequencing mechanisms—that is, mechanisms for specifying rules concerning the order in which independently trackable units of content can be delivered. (In SCORM terminology, these units of content are called shareable content objects, or SCOs. In AICC terminology, they are known as assignable units, or AUs.) However, only the SCORM 2004 specification requires the LMS to support these mechanisms. On the other hand, it's always possible to implement sequencing in a way that is internal to the SCO or AU. So this is only an issue if you aim to reuse SCOs/AUs at a level of granularity below the course level.
Internationalization
The polite term for the AICC specification's support for internationalization is “boneheaded .” In particular, the AICC specification specifically prohibits the use of Unicode character encodings (e.g. UTF-8, UTF-16), instead requiring the use of one of the ISO 8859 family of encodings. Whereas Unicode encodings support virtually all modern languages, the ISO 8859 encodings support only a very limited set of languages, with Asian languages being particularly poorly supported. (Chinese, Japanese and Korean are all unsupported for example.) There's no good reason for this restriction, and in practice many systems "extend" the AICC specifications to support other encodings. (For example, EKP supports a wide range of encodings beyond the ISO 8859 family, including both UTF-8 and UTF-16.) However, a further problem is that the AICC mechanisms provide no clear way to specify which encoding is being used, so trial and error is often necessary in order to ensure non-English text displays as intended.

Friday, January 18, 2008

Tips on integrating Articulate-created content with an LMS

On Articulate's Word of Mouth Blog, Gabe Anderson has posted a useful checklist of things to look for when integrating Presenter- or QuizMaker-created content with an LMS.