Web Application Cloud Engine for edu. Teaser: App Store

I’m currently working with a web application cloud engine, and this is a teaser of a very simple application running in the engine, representing a kind of an App Store making use of open APIs.

Soon we’ll present more advanced web application demos making use of distributed and highly available cloud storage, cross-federated authentication, privacy controls, SOA gatekeeper, and a whole lot of sparkling OAuth love and magic. We may run into WebDAV, WebFinger, Contact search, Invitation, group exchange with VOOT, notifications, gadgets and a lot more.

Stay tuned for updates.

Instant File Sharing using HTML5

I’ve done a proof of concept implementation of a File Sharing web application using HTML5 File API and Drag and Drop API.

The coolest part is that people can start downloading the file, even before the upload is completed.

The implementation is a few lines of code in javascript on the front-end, combined with a small script in Node.js on the server side. Enjoy!

And I wish you a happy christmas as well. Thanks for following my blog!

About reading and writing remote sessions

I’ve recently done some research on third party cookie settings in various browsers. Here are the results.

Disclaimer: I have not went through quality control of the results, so it may contain mistakes.

The tests

Here are some alternative ways the remote page is loaded:

jsredirect
The origin server redirects to the remote server using JS.
jsonp
The origin server loads a script element on the remote server.
iframe
The origin server loads a page on the remote server redirecting back to a receiver on the origin server with query parameters about cookie data, and the loaded page push data to the parent frame.
redirect
The origin server redirects to the remote page using HTTP headers.

I separate between various ways the remote server sets the cookie:

http
The remote server is redirecting back to the origin server using HTTP header redirection, and in the same first response it is setting the Set-Cookie header.
http200
The remote server sets the cookie (with Set-Cookie) with a status code of 200, and a JS script is afterwards redirecting back to the origin site.
js
The remote server is responding with a status code of 200, and a the cookie is set using JS and JS also handles the redirection back to the origin site afterwards.

All tests have performed with and without setting the P3P header on the remote server.

I’ve not testing hidden image elements (or other media elements), but I suspect that the results would be identical as JSONP.

I tested four cookie operatoins for all test cases:

r
Read. Implied if write was successfull. If write fails, read is tested.
w
Write. Implies read. Does it work to set a cookie?
u
Update cookie. Does it work to update a cookie value already set.
d
Delete cookie. Does it work to delete a cookie.

Interesting findings

Here are a summary of what I learned from the research.

All default browser settings are kind to remote read

If you want to read a cookie from a remote site, your good to go with all the approaches with all browsers default setting.

Remote write is more complex

If you want to write a cookie on a remote site, things get more complex.

  • Firefox default settings allows you to do this.
  • Opera does not allow you to write cookie with jsonp nor with hidden iframes; one exception is that it allows you to write cookies in an iframe if you use JS to set the cookie.
  • Safari is very kind and allows you to write remote cookies on a remote site, with one exception: if you are using an iFrame and tries to set the cookie with JS. This is more or less the complete opposite behaviour of Opera.
  • IE allows you to write remote cookies only if you set the P3P header (except in the Low setting). On IE medium + medium high, you may write remote cookies with all approaches except setting cookie with JS in an iframe. On IE High, you are also restricted to not be able to set cookies with JS.

Status code does not matter

When you are using Set-Cookie on the remote server using HTTP header, no browser regardless of settings care about if the status code is 200 or a redirect (back to the origin site).

No browser distinguish between write, update and delete

Operations write, update and delete are always treated the same way, regardless of browser and settings.

Always set P3P headers

IE puts heavy cookie access restrictions unless you set P3P headers – so do that.

Block Third-Party is usally kind towards remote reading, except Firefox

All browsers except Firefox is pretty kind towards allowing you to read cookies on a remote source. With Firefox’s strict setting to block third party cookies, there are no way to read remote cookies wihtout doing a redirect.

Reccomended approach to read remote cookies

Most reliable way to read a remote cookie (without using redirects) is

  • JSONP with setting cookie HTTP header, or
  • iFrame setting cookie using HTTP header.

Works in all browser settings except Firefox block third party setting.

Reccomended approach to write remote cookies

Most reliable way to write a remote cookie (without using redirects) is using two appraches in parallell:

  • Use hidden iFrame and set cookies both in HTTP header and using JS.

Works in all browser settings except Firefox block third party setting.

Reliable front-channel cross-domain communication

I’ve done some more work investigation on how various browsers with various configurations behaves when it comes to access to cookies throuh iframes, redirects, JSONP and images.

I got many use cases where you do not really want to redirect the user to a third party, because you loose control of the user, and you have no way to implement fall-backs from service interruptions on their side.

  • DiscoJuiceReadWrite protocol
  • Identity Federations Virtual Organisations Protocol Design
  • Feide’s Single-Logout implementation

This research is background material for selecting which method to use when doing reliable front-channel cross-domain communication.

I’ll be back with more information on this at a later time. The first preliminary results are that the test is extremely useful, as the behaviour varies a lot between browsers.

Sxipper secure?

Sxipper is an awsome and convenient Firefox tool that makes life simpler and at the same time claims to be secure. Great isn’t it?

Sxipper claims:

Privacy – Sxipper protects your personal data by keeping it secure on your computer and retrieving it for you when you choose to share it online.

But when you enter Sxipper preference panel, you can click Show password, and whoops only a Yes to a question, and there is all your passwords:

Update: After some more playing around with firefox 3 I figured out that if you set a global master password on FF, Sxipper will use that. That’s not too bad. Clever. But what would be even better; if you could use Apple Keychain instead…

Let’s double check:

[sxipper2]$ find . | xargs strings | grep encrypted
{"id":"sxipper@sxip.com","version":"1.0","encrypted":true,"format":"json","type":"complete"}
{"id":"sxipper@sxip.com","version":"1.0","encrypted":true,"format":"json","type":"complete"}
MIIKtAQQ+AAAAAAAAAAAAAAAAAAAATAUBggqhkiG9w0DBwQIs3411U+Vi30EggqIzN0+8aIy5qK/2B7xHL40XlUEQYeEP19jGBPj/VN/hdOJ+94hsluBay5G3tLU6Cr0m78mchijmOA0/0e7zQ2eVN/sy3/FOzduBk4MBcfk2VaRdvhCik6TVo4inDjWRwMIioxSNp4RnNGxB2mH8I18qURi0W0WsrONPscnLlUdp5jnWEeQnu/dXQEIcUKpC8G/QQL6gyPaFG13HeCMoKypGXhuzj1ft1JMlIpKwPjLRuQGjWLIqk/M8pYfGnWglmB[snipp]

Looks encrypted to me. (After some base64 decoding)

Example SAML 2.0 Request and Response

Here are an example SAML 2.0 AuthNRequest and a SAML 2.0 AuthNReponse as sent using simpleSAMLphp protecting a moodle service against Feide as an SAML 2.0 IdP.

To decode SAML 2.0 Requests your self use:

Update: I’ve collected several different authentication request and response messages from different vendors. Go to collection of Example SAML messages

You may also want to check out the Anatomy of SAML Request and Response

Here are the AuthNRequest sent:

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_bec424fa5103428909a30ff1e31168327f79474984" Version="2.0" IssueInstant="2007-12-10T11:39:34Z" ForceAuthn="false" IsPassive="false" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="http://moodle.bridge.feide.no/simplesaml/saml2/sp/AssertionConsumerService.php">
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
        urn:mace:feide.no:services:no.feide.moodle
    </saml:Issuer>
    <samlp:NameIDPolicy xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" SPNameQualifier="moodle.bridge.feide.no" AllowCreate="true" />
    <samlp:RequestedAuthnContext xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Comparison="exact">
        <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
            urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
        </saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

And here is the response:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s2a0da3504aff978b0f8c80f6a62c713c4a2f64c5b" InResponseTo="_bec424fa5103428909a30ff1e31168327f79474984" Version="2.0" IssueInstant="2007-12-10T11:39:48Z" Destination="http://moodle.bridge.feide.no/simplesaml/saml2/sp/AssertionConsumerService.php">
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
        max.feide.no
    </saml:Issuer>
    <samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
        <samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Value="urn:oasis:names:tc:SAML:2.0:status:Success">
        </samlp:StatusCode>
    </samlp:Status>
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="s2b7afe8e21a0910d027dfbc94ec4b862e1fbbd9ab" IssueInstant="2007-12-10T11:39:48Z">
        <saml:Issuer>
            max.feide.no
        </saml:Issuer>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
                <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
                <Reference URI="#s2b7afe8e21a0910d027dfbc94ec4b862e1fbbd9ab">
                    <Transforms>
                        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                        <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                    </Transforms>
                    <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                    <DigestValue>
                        k7z/t3iPKiyY9P7B87FIsMxnlnk=
                    </DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>
                KvUrzGcwGsu8WMNogIRfAxxWlO4uKXhJrouOYaadkzUHvz1xbVURH35si6U8084utNAjXTjZyxfj qurEX7VgCw6Xn7Fxn4nJxD6FOP5x/iRk8KqCufipRNHwICq/VufqPkrP7sVLdymJyZ2Cu5QrEU23 qaIzjFf84Kfp4LVnlJY=
            </SignatureValue>
            <KeyInfo>
                <X509Data>
                    <X509Certificate>
                        MIIB/jCCAWcCBEbzjNswDQYJKoZIhvcNAQEFBQAwRjELMAkGA1UEBhMCTk8xEDAOBgNVBAoTB1VO SU5FVFQxDjAMBgNVBAsTBUZlaWRlMRUwEwYDVQQDEwxtYXguZmVpZGUubm8wHhcNMDcwOTIxMDky MDI3WhcNMDcxMjIwMDkyMDI3WjBGMQswCQYDVQQGEwJOTzEQMA4GA1UEChMHVU5JTkVUVDEOMAwG A1UECxMFRmVpZGUxFTATBgNVBAMTDG1heC5mZWlkZS5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw gYkCgYEAvZlBzQ2jGM6Q9STBJ6tqtugkOBMEU/kpvvwOlT6c1X5UIXMwApL+NV2Eaqk+oA0N+M42 J7Sy0dLDqKVCwsh7qpsIYlDS/omyUMdy6AzvptRUUhLLhC6zQFFAU+6rcUKEiSkER5eziB4M3ae0 EkW0drm1rOZwb22tr8NJ65q3gnsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCmVSta9TWin/wvvGOi e8Cq7cEg0MJLkBWLofNNzrzh6hiQgfuz9KMom/kh9JuGEjyE7rIDbXp2ilxSHgZSaVfEkwnMfQ51 vuHUrtRolD/skysIocm+HJKbsmPMjSRfUFyzBh4RNjPoCvZvTdnyBfMP/i/H39njAdBRi+49aopc vw==
                    </X509Certificate>
                </X509Data>
            </KeyInfo>
        </Signature>
        <saml:Subject>
            <saml:NameID NameQualifier="max.feide.no" SPNameQualifier="urn:mace:feide.no:services:no.feide.moodle" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
                UB/WJAaKAPrSHbqlbcKWu7JktcKY
            </saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml:SubjectConfirmationData NotOnOrAfter="2007-12-10T19:39:48Z" InResponseTo="_bec424fa5103428909a30ff1e31168327f79474984" Recipient="http://moodle.bridge.feide.no/simplesaml/saml2/sp/AssertionConsumerService.php">
                </saml:SubjectConfirmationData>
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2007-12-10T11:29:48Z" NotOnOrAfter="2007-12-10T19:39:48Z">
            <saml:AudienceRestriction>
                <saml:Audience>
                    urn:mace:feide.no:services:no.feide.moodle
                </saml:Audience>
            </saml:AudienceRestriction>
        </saml:Conditions>
        <saml:AuthnStatement AuthnInstant="2007-12-10T11:39:48Z" SessionIndex="s259fad9cad0cf7d2b3b68f42b17d0cfa6668e0201">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>
                    urn:oasis:names:tc:SAML:2.0:ac:classes:Password
                </saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
        <saml:AttributeStatement>
            <saml:Attribute Name="givenName">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    RkVJREUgVGVzdCBVc2VyIChnaXZlbk5hbWUpIMO4w6bDpcOYw4bDhQ==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="eduPersonPrincipalName">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    dGVzdEBmZWlkZS5ubw==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="o">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    VU5JTkVUVA==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="ou">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    VU5JTkVUVA==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="eduPersonOrgDN">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    ZGM9dW5pbmV0dCxkYz1ubw==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="eduPersonPrimaryAffiliation">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    c3R1ZGVudA==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="mail">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    bW9yaWEtc3VwcG9ydEB1bmluZXR0Lm5v
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="preferredLanguage">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    bm8=
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="eduPersonOrgUnitDN">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    b3U9dW5pbmV0dCxvdT1vcmdhbml6YXRpb24sZGM9dW5pbmV0dCxkYz1ubw==
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="sn">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    RkVJREUgVGVzdCBVc2VyIChzbikgw7jDpsOlw5jDhsOF
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="cn">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    RkVJREUgVGVzdCBVc2VyIChjbikgw7jDpsOlw5jDhsOF
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="eduPersonAffiliation">
                <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
                    ZW1wbG95ZWU=_c3RhZmY=_c3R1ZGVudA==
                </saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>

GÉANT JRA5

(stolen from JRA5 webside): Before the vision of a truly open European research area can be realised, it must be possible to establish interoperable access to the networks that interconnect to form the research networking supply chain in Europe. To the user, the multiple networks must appear to be one seamless resource. A researcher visiting a collaborator in Paris should be able to log on to the network and access the local resources on his computer in Poznan easily.


The GÉANT2 JRA5 working group is running two projects. eduroam for interconnecting wireless networks across Europe, and eduGAIN for interconnecting authentication and authroization infrastructures from the participating countries.

Feide is participating involved in both eduroam and eduGAIN. Feide’s involvement in eduGAIN includes among other activives to design and implement the Feide bridiging element to enable Feide services and IdPs to work with other services and IdPs connected to eduGAIN.

Resources