This demonstration shows how the content
from a remote repository and the client components of a LMS can
communicate with each other without violating the browser's
cross-platform scripting security rules.
The demonstration relies on network
infrastructure in the form of a reverse proxy
server. The reverse proxy is a safe method to deploy content
from different origins through a common server.
Interactive Demo 1
The frame below displays content from two
different servers: a web page and, within a frame within that
page, a different web page. To test this, click the buttons
above the frame to choose how to load the content. A step by
step demo guide is shown below the frame.
Note: Because the reverse proxy used
in this demo is currently running on a private DSL connection,
it may not always be available and bandwidth is limited. Please
drop me a note at tools@ostyn.com if
the demo does not work.
Demo steps:
Click the "Load from separate servers" button. There
should now be two pages in the frame, an "outer page" and
an "inner page" displayed in a frame within the "outer
page."
Read the URL and server information displayed by each
page. Each page captures the information about where it is
coming from using JavaScript, and then displays it using
DHTML within the page itself. Notice that the servers are
different. They are not only different domains, they are
actually provided by completely independent hosting
services. One is in Illinois, the other in Colorado.
In the outer page, click the "Test communication with
content in frame" button. This invokes a script that tries
to get the title of the inner page. You should get an error
message, since this is cross-domain scripting and is not
allowed by browser security. If you do not get an error here then
your browser is vulnerable to cross-scripting exploits and
you should correct that before doing any more Internet
surfing.
In the inner page, type in something then click the
"Set value through cross-frame scripting". Again, you
should get an error since this is cross-domain scripting
and is not allowed by browser security.
Click the "Load through reverse proxy" button.
Read the details displayed when you click the Load
through reverse proxy button. Notice how the reverse proxy
controls access to the remote content servers by using a
specific mapping. Cross-domain access is tightly managed
and controlled by the reverse proxy.
Read the URL and server information displayed by each
page. This time they will show that they come from the same
server. Note: There is no cheating. Those are the very
pages you saw a minute ago, coming from the very same
servers, except that now you are accessing them through a
reverse proxy server.
In the outer page, click the "Test communication with
content in frame" button. This invokes a script that tries
to get the title of the inner page. This should work
because it is allowed by browser security.
In the inner page, type in something then click the
"Set value through cross-frame scripting". Again, this
should work.
Click the "Load foreign page" button in the outer page
and type in a URL. The outer page will now try to load an
unknown page through the reverse proxy. Because it is not
configured to accept this request, the reverse proxy will
refuse it or redirect to a safe page. Security has been
maintained.
You may repeat the demo or change the order of steps as
often as you like.
Interactive Demo 2
Demo 1 showed some simple custom content.
But what about a real SCO? Demo 2 uses a test harness that
simulates a LMS and a diagnostic SCO that shows how the API can be
found and allows one to exercise various features of the API
through an entire SCORM communication session from Initialize
to Finish. The frame below displays content from two different
servers on two different domains. This harness comes from the
Illinois server and this diagnostic SCO resides on the Colorado
server. A step by step guide to the demo can be found below the
demo frame.
Demo steps:
Click the "Load from separate servers" button. There
should now be two pages in the frame, an "outer page" which
is the test harness, and an "inner page" which is the test
SCO displayed in a frame within the test harness.
Notice that the RTE info in the test SCO states that no
SCORM API is available. The API "icon" in the test SCO is
red and shows no SCORM version. If you scroll down to look
at the window analysis information in the test SCO, you
will see that no API object can be found and no information
is available about the containing windows.
Click the "Load through reverse proxy" button.
Notice that the RTE info in the diagnostic SCO states that a
SCORM 2004 API is available. The API "icon" in the test SCO
is green and shows the SCORM version. If you scroll down to
look at the window analysis information in the diagnostic SCO,
you will see that the API object was found in a parent
window and other information is available about the
containing windows.
In the diagnostic SCO, click the "Scripted Test" tab. Click the
Demo button to load a demo script, then click Run Script.
Notice how the API calls are logged both in the test SCO
and the test wrapper, and how the test wrapper responds to
good and bad calls.
The demo scripts went through an entire API session
that ended when it calls Terminate(). Reload the SCO (you
can click the Load button in the test harness or the Reload
through Proxy button above). Click the API Prodder tab.
Click Initialize and then play with SetValue, GetValue and
Commit at will. Click Terminate to end the API
session.
You may repeat the demo or change the order of steps as
often as you like.
How it works
This demo purposedly does not use a real
LMS and a real SCO to keep things obvious and to avoid the cost
of exposing a real LMS server to the Internet. But the
technology used in the demo for communication between two pages
from different server is identical to the technology used by a
SCO to communicate with the SCORM runtime environment provided
by a LMS.
Figure - The setup for these demos
The reverse proxy is an Apache 2.2.x server
configured with two virtual directories named "ostyn" and
"snj", respectively. Requests for content in the "ostyn" branch
are forwarded to a specific origin server, and those for
content in the "snj" branch are forwarded to another specific
origin server. This particular reverse proxy server is not
configured to do anything else. It is running on an old box
from my computer recycling pile. If another content repository
needs to be added to the mix, this can be done in a couple of
minutes by adding another virtual directory, restarting Apache
(which takes only seconds) and testing that the reverse proxy
works as expected. Attempts to reach other servers through this
reverse proxy will fail.
Any browser. The work takes place in a managed server. No
browser tricks or configuration changes are required. A far as the browser is
concerned, it all comes from a single server.
Is this section 508/accessibility standards
conformant?
There is nothing in this functionality that inhibits
accessibility standards conformance.
Cross-server scripting is bad. Isn't this dangerous?
No. Any cross-server scripting that takes place is strictly controlled
by the settings of the server-side reverse proxy. Only specific servers are allowed
to participate in these transactions. The single origin rule still
applies to the browser, because from the browser's perspective there
is only one server.
Does this work if my LMS uses popup pages?
Yes.
Does this work with any LMS?
Unfortunately no. Some LMS implementations may require
modification or are architected in such a way that it is very
difficult to work with them through a reverse proxy. But in
many cases the reverse proxy can be combined with the LMS
server and in that case only the content is actually coming
from a different server.
We're a Microsoft shop and we don't want to hear about
Apache. Does this work with a Microsoft proxy?
Not sure. ISA 2004 Server documentation hints that it can
be used as reverse proxy for multiple servers from different
domains, but so far I only found documented examples where
the servers were all in the same LAN. Open hint to anyone
working for Microsoft: If you want this demo and the
technical document to also feature Microsoft's solutions,
please step forward with the means to do so.
Does this work with any content?
It should work with any SCORM content that is truly
portable, i.e. content that can be installed on any web
server and relies only on relative links. Server-dependent
content may work or not, depending on how it is coded. Some
server-dependent content relies on hardwired cookies that may
prevent reverse proxying. Until Apache 2.0 this was basically
not possible with an Apache reverse proxy, but 2.0 introduced
cookie rewriting to handle at least some of those cases.
Still, all assets links in the content should be relative,
unless they are referencing non-communicative assets such as
pictures and media files. For example, an .aspx page might
use a video stream that can be referenced with an absolute
URL so it does not have to go through through the reverse
proxy.
Note that we did run into a problem with the most recent mod_security (2.1.1)
module for Apache. One of the default rules is a little too aggressive. It
scans the HTTP response and blocks any content that contains some javascript
statements.
Disabling that rule solved the problem. The rule is in
modsecurity_crs_50_outbound.conf. It is only the SecRule RESPONSE_BODY that does
not have a specific .msg specified.
Does the content need to be modified?
The SCOs themselves don't need to be modified in any way.
However, depending on how a LMS sets up the base path for the
content it lauches, the LMS may have to massage the domain
parts of the URLs, it may be necessary to modify the URLs in
the manifest to ensure that the path in each SCO launch URL
in the resource elements to matche the virtual directory in
the reverse proxy. How to do this could be standardized (see
paper on www.ostyn.com). A promising solution is to use
CORDRA, as in the ADL Repository. A LMS that can recognize
the href values in the resource elements as CORDRA handles
can use a resolution service to get a URL that maps exactly
to a reverse proxy, and then use that URL to launch the SCO.
After that, all relative URLs within the SCO are resolved
automatically by the browser.
Does it work with server-dependent content such as active
pages (.asp, .jsp, .php)?
Yes. However there may be some limitations where cookies
are concerned. See the Apache mod_proxy documentation for
details. It will also not work if the active pages are
generating absolute rather than relative embedded links. For
example, if a SCO contains a hyperlink to the next page in
the SCO, that link must be relative and not absolute,
otherwise the browser won't be able to resolve it. Links to
passive assets or to assets for which no cross-scripting is
required may be absolute links if performance is a big issue,
but such links may diminish the future possibilities to
migrate the application to another server.
I tried to type the URL of my SCO in the second demo, but
it did not work
This is as it should be. It just shows that the reverse
proxy is secure. The reverse proxy server will deny any
request for content that is on a server for which a virtual
path has not been configured. If you have an Internet
accessible SCO that you would like to try, drop me a line at
tools @ ostyn.com and, after a security check, we can try to
add a path in the reverse proxy.
What is the performance cost?
Although every hop to another server does affect
performance, in practice the impact appears to be acceptable.
You should be able to see some difference in this demo. The
main limitation for this demo is that the reverse proxy
server is an old, slow computer that is sharing very limited
upload bandwidth on a home DSL connection, but in a real
deployment the connections would typically be done through a
fast network. Proxying of web content takes place all the
time on the web, in enterprise firewalls and in server farms
and most people cannot tell when it is happening. However
proxying for large media assets and streaming content may not
be such a hot idea. Those are better accessed through fully
qualified URLs that point directly to an interactive server.
Note that cross-domain scripting issues don't usually arise
with that type of content.
What about SSL?
That is much more difficult to set up, but it appears to
be quite doable. See the Apache and Microsoft ISA 2004 server
technical pages and online communities for information about
SSL and reverse proxies. This is way beyond what a typical
LMS, database or network administrator can grasp, however. If
you need SSL you need someone who lives and breathes the low
level Internet and network protocols.
Does this also work with SCORM 1.2?
Yes.
I tried to set up a reverse proxy but it does not work
with my content
First check whether all the links in the SCOs are
relative to the launch page for the SCO. In other words, make
sure that the content is portable or at least that the
internal links and references to other web content are
portable. If this is server-dependent content, install a copy
on another server at a different directory depth to verify
that it does not have hard wired dependencies or references
to a particular parent directory configuration.