easyXDM – Rantings in the dark https://kinsey.no/blog Because I want to be like the cool kids too Sun, 21 Apr 2019 23:19:33 +0000 en-US hourly 1 https://wordpress.org/?v=5.8.18 How to set up an AD backed OpenID Provider without direct communication https://kinsey.no/blog/index.php/2010/07/09/how-to-set-up-an-ad-backed-openid-provider-without-direct-communication/ https://kinsey.no/blog/index.php/2010/07/09/how-to-set-up-an-ad-backed-openid-provider-without-direct-communication/#comments Fri, 09 Jul 2010 17:11:41 +0000 http://kinsey.no/blog/?p=290 I’ve currently got a project where I need to provide an OpenID Provider (OP) to authenticate users using Active Directory (AD), something that shouldn’t be to much of a hassle.
But there is a catch: the OP needs to be outside the firewall in order to talk to the Relying Parties (RP) and is unable to communicate directly with AD. So what can you do?

Well, in this case the OP is only going to be used by users that are sitting behind the firewall, and who have access to both internal resources and external resources over port 80, and what this means is that we can use the client (the browser) to relay messages between the OP and the asserting party. In order to make the communication going via the browser trusted, we can use a challenge combined with symmetric encryption to verify authenticity.

This means that the chain of trust needed for the identity assertion looks like the following

  • The RP trust the assertion from the OP
    • The RP and the OP shares can communicate directly and uses a shared secret to verify the authenticity of the message passed through the browser
  • The RP trusts the assertion from the Internal Webserver (IW)
    • The RP and the IW has a pre-shared encryption key that together with a challenge serves to verify the authenticity of the messages passed through the browser

In the following code DotNetOpenAuth is used to provide support for OpenID, and easyXDM is used to provide the Cross-Document Communication.
Codewise, it all starts once the OpenID request hits the OP, and at this point we only store away the request and render a blank page containing the following JavaScript

// server.aspx
// This is called by ASP.NET Ajax once the page is ready
function pageLoad() {
    // Set up a new easyXDM.Rpc object
    var rpc = new easyXDM.Rpc({
        remote: "http://localhost:55192/Endpoint.aspx"
    }, {
        remote: {
            authenticate: {}
        }
    });

    // Retrieve a challenge from the server 
    PageMethods.GetChallenge(function (challenge) {
        // Relay the challenge to the internal webserver
        rpc.authenticate(challenge, function (response) {
            // Relay the response back to the server
            PageMethods.VerifyResponse(response, function (verified) {
                // If the response was verified, we redirect to the page that will complete the OpenID assertion
                if (verified) {
                    location.href = "complete.aspx";
                } else {
                    alert("not authenticated");
                }
            });
        });
    });
}

As you can see this uses PageMethods to talk to the server side code for retrieving the challenge, and for delivering the response

'server.aspx
<WebMethod()> _
Public Shared Function GetChallenge() As Utilities.Challenge
    ' This method is called to create a challenge, and to get access to the claimed identifier that the internal webserver will have to verify
    ' Create and store away a challenge
    Dim challenge As New Utilities.Challenge
    challenge.Guid = System.Guid.NewGuid().ToString()
    HttpContext.Current.Session("guid") = challenge.Guid

    If providerEndpoint.PendingAuthenticationRequest IsNot Nothing Then
        challenge.Identifier = providerEndpoint.PendingAuthenticationRequest.ClaimedIdentifier.OriginalString
    End If
    ' Return a Plain Old CRL Object (POCO). This will be serialized into JSON
    Return challenge
End Function

<WebMethod()> _
Public Shared Function VerifyResponse(ByVal response As String) As Boolean
    ' This method will be called after the response returns from the internal webserver
    If providerEndpoint.PendingAuthenticationRequest IsNot Nothing Then
        Dim enc = New Utilities.SymmetricEncryption("my secret")
        ' Encrypt the claimed identity and the stored challenge, and see if it matches the response from the internal server
        If enc.Encrypt(providerEndpoint.PendingAuthenticationRequest.ClaimedIdentifier.OriginalString & "_" & HttpContext.Current.Session("guid")) = response Then
            ' If it matches we issue an authentication token
            FormsAuthentication.SetAuthCookie(providerEndpoint.PendingAuthenticationRequest.ClaimedIdentifier, False)
            Return True
        End If
    End If
    Return False
End Function

On the internal server the setup is similar, we accept the claimed identity, verify it against the identity of the authenticated user, and return a signed response.
Here we expose a method whose only purpose is to relay the challenge back to the serverside code

// Endpoint.aspx
// This is called by ASP.NET Ajax once the page is ready
function pageLoad() {
    // Set up a new easyXDM.Rpc object
    var rpc = new easyXDM.Rpc({}, {
        local: {
            authenticate: function (challenge, fn) {
                // Relay the challenge to the serverside code
                PageMethods.Authenticate(challenge, function (response) {
                    // Relay the response back to the OP
                    fn(response);
                });
            }
        }
    });
}

Here we extract the username from the claimed identifier and compare it to the known one. If it matches we return an encrypted response

'Endpoint.aspx
<WebMethod()> _
Public Shared Function Authenticate(ByVal challenge As Utilities.Challenge) As String
    ' This is called to check wether the claimed identifier matches the known one
    Dim claimedUserName As String = New Uri(challenge.Identifier).Query.Substring(4)

    If HttpContext.Current.User.Identity.IsAuthenticated Then
        Dim username As String = HttpContext.Current.User.Identity.Name
        username = username.Substring(username.IndexOf("\") + 1)
        If username = claimedUserName Then
            ' If it matches we encrypt the identifier and the challenge, and return the result as the response
            Dim enc = New Utilities.SymmetricEncryption("my secret")
            Return enc.Encrypt(challenge.Identifier & "_" & challenge.Guid)
        End If
    End If

    Return String.Empty
End Function

One of the interesting things here is how the instances of Utilities.Challenge is serialized and deserialized going from the OP’s server side code to the client side code, and again serialized and deserialized going from the internal webservers client side code to the internal webservers server side code. Like magic right?

(Of course, we could easily have used a couple of redirects instead of the server-client-client-server communication, but that wouldn’t have been as fun now would it 🙂

]]>
https://kinsey.no/blog/index.php/2010/07/09/how-to-set-up-an-ad-backed-openid-provider-without-direct-communication/feed/ 4
easyXDM 2.0 out, now with a proper website! https://kinsey.no/blog/index.php/2010/03/19/easyxdm-2-0-out-now-with-a-proper-website/ https://kinsey.no/blog/index.php/2010/03/19/easyxdm-2-0-out-now-with-a-proper-website/#comments Fri, 19 Mar 2010 11:50:59 +0000 http://kinsey.no/blog/?p=285 See http://easyxdm.net/wp/2010/03/17/easyxdm-2-0-now-even-with-a-new-website for more information!

]]>
https://kinsey.no/blog/index.php/2010/03/19/easyxdm-2-0-out-now-with-a-proper-website/feed/ 2
The upcoming release of easyXDM v2.0 https://kinsey.no/blog/index.php/2010/03/16/the-upcoming-release-of-easyxdm-v2-0/ https://kinsey.no/blog/index.php/2010/03/16/the-upcoming-release-of-easyxdm-v2-0/#comments Mon, 15 Mar 2010 22:48:55 +0000 http://kinsey.no/blog/?p=276 Major improvements has been added to the project and I am proud to soon be able to release version 2.0, a release that features a new and simpler API, and a stack approach that is highly customizable when it comes to adding new features.

I would really love to get some feedback on the current state before releasing the new version, so as to make it as successful as possible, and so I turn to you.

Please, take a look at the repository at http://github.com/oyvindkinsey/easyXDM/, view the new documentation at http://easyxdm.net/v2.0.0/docs/, run the tests at http://easyxdm.net/v2.0.0/tests/ or download the code at http://easyxdm.net/v2.0.0/source.zip, and if you feel like it, give me some feedback either on this mailing list, or as an Issue at Github.
Some of the new features planned can be viewed at http://wiki.github.com/oyvindkinsey/easyXDM/planned-features, and I’ll continue to update this list as new ideas show up.

By the way, moving to the new API is really simple and only requires a few small changes – this is all shown in the examples.

And to show one of them, here is the new xhr.html sample, which shows how to use the easyXDM.Rpc (the old Interface class) together with the bundled xhr.html document.

var xhr = new easyXDM.Rpc({
    local: "../hash.html",
    remote: remoteUrl + "/../xhr.html",
    remoteHelper: remoteUrl + "/../hash.html"
}, {
    remote: {
        post: {}
    }
});

This will give you an instance of easyXDM.Rpc that exposes a method quite similar to the one many frameworks use for doing AJAX calls…

xhr.post("example/glossary.php", {
    param1: "a",
    param2: "b"
}, function(json){
    alert(json.glossary.title);
});

.. and hey presto, you have cross-domain AJAX without the inherent security issues that other approaches like JSONP has.
By the way, if anybody wants to contribute (as some has started to) feel free to do so!
What the project needs the most is a decent logo, a proper website (maybe something like http://www.dotnetopenauth.net/) and to have the documentation extended with samples etc like the ones at http://www.extjs.com/deploy/dev/docs/?class=Ext.form.ComboBox .

Also, if you want to stay up to date on new releases, ask questions  etc. then there is now a new google group created for this at http://groups.google.com/group/easyxdm

]]>
https://kinsey.no/blog/index.php/2010/03/16/the-upcoming-release-of-easyxdm-v2-0/feed/ 2
easyXDM v1.8.0 relased https://kinsey.no/blog/index.php/2010/02/27/easyxdm-v1-8-0-relased/ https://kinsey.no/blog/index.php/2010/02/27/easyxdm-v1-8-0-relased/#comments Sat, 27 Feb 2010 19:19:12 +0000 http://kinsey.no/blog/?p=269 A lot has been going on with easyXDM over the past week, and I am proud to finally be able to release a version where all transport types, even the ones for IE6, deliver the same set of features.

From now on all the transports (and all the relying classes) supports

  • Reliability, ‘guaranteed’ delivery of messages
    The new ReliableBehavior adds this to the HashTransport
  • Sender-verification,  verifying that the message originates from the original sender. This removes the risk of malicious sites spoofing the sender
    This is added to the HashTransport and NameTransport by the VerifyBehavior
  • Queueing, you can now send multiple messages in the same js thread
    This is added to the HashTransport and NameTransport by the QueueBehavior

Behaviors

So what are these behaviors mentioned? Well, a behavior modifies the way a transport works, and it works by sending all events and messages through a pipeline of behaviors, where each one can let it pass, inspect it, modify it, block it etc. Each behavior is automatically chained with the others so that they form a stack, where in principal, each layer talks to the corresponding layer on the other end.

One example of this in action is the fragmentation. When the QueueBehavior receives an outgoing message that is larger than the max fragment size, then instead of queueing only one message, it will queue each fragment with a fragment identifier. The QueueBehaviors dispatcher will then send each message as fast as it can (it gets a callback from the next Behavior in he line when the message is delivered).

On the other end multiple ingoing messages will received at the QueueBehavior, but the message won’t be passed on until all fragments has arrived.

Using behaviors instead of applying the functionality directly to the classes adds a lot to the table

  • Re-usability, the same behavior can be applied to all transports that accepts these.
  • Separation, each new feature is contained in a separate class, and since the pipeline is layered, you can safely introduce e.g sender-verification without risking breaking the code that handles the sending/receiving.
  • Structure, the code is a lot easier to read and understand, and adding new behaviors is a breeze.

This is a sample from the HashTransport and shows how behaviors are applied internally

easyXDM.applyBehaviors(this, [
    new easyXDM.transport.behaviors.ReliableBehavior({
        timeout: ((useResize ? 50 : pollInterval * 1.5) + (usePolling ? pollInterval * 1.5 : 50))
    }),
    new easyXDM.transport.behaviors.QueueBehavior({
        maxLength: 4000 - _remoteUrl.length
    }),
    new easyXDM.transport.behaviors.VerifyBehavior({
        initiate: isHost
    })
]);

In the future these will be overridable, and you will be able to inject your own if you want to.

Conclusion

If you haven’t already, go download the newest version and enjoy the new features!

]]>
https://kinsey.no/blog/index.php/2010/02/27/easyxdm-v1-8-0-relased/feed/ 5
easyXDM – finally with queuing and fragmenting! https://kinsey.no/blog/index.php/2010/02/22/easyxdm_and_queuing/ https://kinsey.no/blog/index.php/2010/02/22/easyxdm_and_queuing/#comments Mon, 22 Feb 2010 18:11:43 +0000 http://kinsey.no/blog/?p=261 With the newest release, 1.7.4 (see the commits here), we have added two important features, fragmenting for the HashTransport, and queing for both the HashTransport and NameTransport

Fragmenting

The first is definitely something that many has been waiting for, until now the HashTransport class just didn’t cope with messages that would create URLs longer than 4095 character (the maximum size allowed by IE6). If a longer message was send (something that could easily happen when using the Interface class), the transport would just fail. But not anymore, you are now able to send however long messages you’d like, and of course, this was all made possible with the new queuing feature.

Queuing

Until now, when you tried to rapidly send messages, if you were so unfortunate to do so before the message had been read, it would be overwritten. This was especially easy to do when the HashTransport was in polling mode, as it then only checks for new messages every 300ms.

Both the HashTransport and the NameTransport has now been extended with a live casino sites queuing feature, meaning that all messages will first go into a queue, which will then be emptied in a LIFO fashion.

Conclusion

easyXDM just got even better, thats about it. The only known feature request as it is now is message receipts, making the transport completely reliable, but I’m think this probably belongs in the Channel class..

By the way, the Continual Integration system has now been set up so that the test suite for the current head from GitHub will always be available at http://easyxdm.net/dev/tests/.

And one final thing: The project has finally got its first contributors!

]]>
https://kinsey.no/blog/index.php/2010/02/22/easyxdm_and_queuing/feed/ 7
Resizing iframes using easyXDM https://kinsey.no/blog/index.php/2010/02/19/resizing-iframes-using-easyxdm/ https://kinsey.no/blog/index.php/2010/02/19/resizing-iframes-using-easyxdm/#comments Fri, 19 Feb 2010 16:52:35 +0000 http://kinsey.no/blog/?p=252 One thing that many are using easyXDM (and other cross-domain hacks) for, is to dynamically change the size of embedded iframes based on the contents size, so as to avoid the scrollbars.

To make it easier to do this using easyXDM, I have now published an example how how to do this here.

It really is easy, on the page hosting the iframe you use the following to load the iframe

var transport = new easyXDM.transport.BestAvailableTransport({
    local: "../hash.html",
    remote: "http://provider.easyxdm.net/example/resized_iframe.html",
    container: document.getElementById("element_that_should_contain_the_frame"),
    onMessage: function(message, origin){
        this.container.getElementsByTagName("iframe")[0].style.height = message + "px";
    }
});

And then you put the following in the iframes body after the content

var transport = new easyXDM.transport.BestAvailableTransport({}, function(){
    transport.postMessage(document.body.scrollHeight);
});

Thats it!
Again, the sample can be viewed here.

]]>
https://kinsey.no/blog/index.php/2010/02/19/resizing-iframes-using-easyxdm/feed/ 10
easyXDM just became even easier to use! https://kinsey.no/blog/index.php/2010/01/02/easyxdm-just-became-even-easier-to-use/ https://kinsey.no/blog/index.php/2010/01/02/easyxdm-just-became-even-easier-to-use/#comments Sat, 02 Jan 2010 19:56:04 +0000 http://kinsey.no/blog/?p=201 To accommodate older browsers that does not implement the postMessage interface, easyXDM is able to fall back to using the URI fragment trick, and until now this has meant that the provided hash.html file had to be uploaded to the local domain (the ‘calling’ domain).

This seems to be a dealbreaker for many as they are unable to upload files to the server, either due to special systems, or because they just want to present an API in the form of ‘just include this javascript file’ etc..

With the new 1.5.5 release, this has all changed.

For scenarios where you do not want to upload the hash.html file, you can now point the local attribute to any file present on the local domain, like robots.txt or favicon.ico, and supply a readyAfter attribute with the number of milliseconds to wait before assuming the local file to be loaded and the library to be ready for interaction.

{
local: "/robots.txt",
readyAfter: 1000,
remote: "http://.........",
...
}

Update: Just released 1.6.0 which makes it possible to utilize the current document instead of loading a new one from the local domain. This makes it very easy to integrate, but does mean that you will be modifying the documents location when falling back to the HashTransport – and this might interfere with for instance history managers etc.

{
local: window,
remote: "http://.........",
...
}

The hash.html file is still the recommended approach for stable
implementations as it is unobtrusive and it guarantees that the library is indeed ready
when transitioning into a ready state.
Using hash.html also shortens the time needed to initialize easyXDM
as there is no need for the delay to give the local file time to
properly load.

All the different ways to set up easyXDM can now be viewed at http://easyxdm.net/wiki/Documentation.ashx

]]>
https://kinsey.no/blog/index.php/2010/01/02/easyxdm-just-became-even-easier-to-use/feed/ 4
Widget support added to easyXDM! https://kinsey.no/blog/index.php/2009/09/06/119/ https://kinsey.no/blog/index.php/2009/09/06/119/#comments Sun, 06 Sep 2009 14:37:39 +0000 http://kinsey.no/blog/?p=119 The newest version of easyXDM (v1.5.3) now includes two new classes, the easyXDM.WidgetManager, and easyXDM.Widget.

These make it extremely easy to make mashups based on the subscribe/publish architecture.

To read more about easyXDM check out this blog post.

The widget demo can be found at http://consumer.easyxdm.net/current/example/widgets.html,  and if you want to, just copy the code for the widget found here, modify the src for the scripts and save it to your own domain – you should now be able to add it from the WidgetManager!

The WidgetManager

To set up a page to contain widgets we need an instance of the WidgetManager:

var _widgetManager = new easyXDM.WidgetManager({
    local: "../hash.html",
    container: document.getElementById("widgets")
 });

And with the widgetmanager set up we continue by adding widgets by their url

_widgetManager.addWidget("http://provider.easyxdm.net/example/widget.html",{});

And thats it 🙂

The widgets

Creating a widget isn’t much more work

The following is a skeleton widget

var widget = new easyXDM.Widget({
    subscriptions: ["testtopic"],
    initialize: function(widget, widgetManager){
        // Set up the widget

        // Render the UI

        // Register the handler for incoming messages
        widget.registerMessageHandler(function(url, topic, data){
            // Do something
        });
    },
    initialized: function(widget, widgetManager){
        //This is called after the widget has been initialized by the widgetmanager
    }
});

To create a custom widget you only need to select the internet slots canada topics to subscribe to, build the UI, and handle the incoming messages the way you see fit.

To publish your own messages you simply use widget.publish  like this

widget.publish("position", {
    latitude: "60.378776",
    longitude: "5.337811"
});

and all subscribers will get this.

It’s that easy!

]]>
https://kinsey.no/blog/index.php/2009/09/06/119/feed/ 2
easyXDM – extremely easy cross-domain scripting https://kinsey.no/blog/index.php/2009/08/20/easyxdm/ https://kinsey.no/blog/index.php/2009/08/20/easyxdm/#comments Thu, 20 Aug 2009 15:03:02 +0000 http://kinsey.no/blog/?p=84 easyXDM is a javascript library that uses available techniques to provide a means of transporting messages and/or method calls between windows in different domains, in short, by-passing the same-origin policy and letting you call methods across the domain boundry.

This is perfect if you plan to provide a client-side API (e.g Facebook Connect) on your web site as you can expose a method in as little as 7 lines of code.

var remote = new easyXDM.Interface({}, {
    local: {
        doMagic:{
            method: _privateMethod
        }
    }
});

This can be consumed by a client by using

var remote = new easyXDM.Interface({
   local: &quot;../hash.html&quot;,
   remote: &quot;http://apiprovidersdomain.com/api.html&quot;
},{
    remote: {
        doMagic: {}
    }
});

and can then be called by using

remote.doMagic('argument1',2,function(result){
    alert(result)
}

In this CodeProject article I present an example on how easy it is to do this, and in the extensive documentation there are links to several demos showing everything from sending simple strings to letting two applications from different domains send arbitrary objects back and forth, even using older browsers like IE6.

The demos are repeated here

This library was earlier on called easyXSS, but due to the name being kinda ambiguous (someone say vulnerability), I decided to change it to easyXDM, short for easy cross domain messaging.

If you want to sneak a peek at the sourcecode, you can see the fully documented debug version here. The minified version weighs in at only 1.46KB gzipped.

The library is very flexible, allowing you you choose exactly how much of the work you want to handle yourself, the base functionality is transferring string messages.

Some of the features are

  • transport classes for transmitting strings
    • postMessage where supported OR
    • hash fragment using the resize event for invisible iframes
    • hash fragment using polling for visible frames
  • channel class for transmitting aribitrary data
  • interface class for setting up methods to be exposed/consumed
  • debug build with extensive logging for easy debugging
  • works in all browser (run the test suite)

The library also support both visible and invisible iframes, so you can either access the aussies casino online remote domain transparently, or you can expose the remote domains document for direct interaction (sign in etc.).

<ul>
<li>
<a href=”http://consumer.easyxdm.net/example/transport.html”>Sending plain string messages using the easyXDM.Transport.BestAvailableTransport class</a>
</li>
<li>
<a href=”http://consumer.easyxdm.net/example/data.html”>Sending data (objects)  using the easyXDM.Channel class</a>
</li>
<li>
<a href=”http://consumer.easyxdm.net/example/methods.html”>Exposing and invoking methods using the easyXDM.Interface class</a>
</li>
<li>
<a href=”http://consumer.easyxdm.net/example/xhr.html”>Calling an ajax method from the remote domain</a>
</li>
<li>
<a href=”http://consumer.easyxdm.net/example/index.html”>Bridging two web applications</a>
</li>
</ul>
]]>
https://kinsey.no/blog/index.php/2009/08/20/easyxdm/feed/ 88
easyXSS https://kinsey.no/blog/index.php/2009/06/24/easyxss/ https://kinsey.no/blog/index.php/2009/06/24/easyxss/#comments Wed, 24 Jun 2009 16:39:38 +0000 http://kinsey.no/blog/?p=44 Please see easyXDM for updated info!

I’ve just completed the first version of my cross-site scripting library easyXSS. It is available at http://code.google.com/p/easyxss/ under a MIT-license.

As it is now it supports simple messaging between windows of different domains, but it also supports proxying method calls and results between them making it well-suited for creating API’s.

I’ve prepared several examples and demo’s at http://code.google.com/p/easyxss/ and look forward to getting feedback!

To show you a quick example, here is the code needed to have a method ‘doMagic’ that is located on domainA available in a window from domainB.

This is placed in the document api.html at domainA

var channel = easyXSS.createChannel({
onReady: function(){
remote = easyXSS.createInterface(channel, {
local: {
doMagic: _privateMethodDoingMagic
}
});
}
});

and this is placed in the document at domainB

var remote;
var channel = easyXSS.createChannel({
local: &quot;/hash.html&quot;,
remote: &quot;http://domaina.com/api.html&quot;,
onReady: function(){
remote = easyXSS.createInterface(channel, {
remote: {
doMagic: {}
}
});
}
});

The medhod doMagic can now be called from domainB using

remote.doMagic('argument1',2,'three',function(result){
// Consume the result
});
]]>
https://kinsey.no/blog/index.php/2009/06/24/easyxss/feed/ 12