ASP.NET WebAPI Security 5: JavaScript Clients

Posted by Your DisplayName here! on Least Privilege See other posts from Least Privilege or by Your DisplayName here!
Published on Thu, 15 Mar 2012 08:56:42 GMT Indexed on 2012/03/18 18:19 UTC
Read the original article Hit count: 415

Filed under:
|

All samples I showed in my last post were in C#. Christian contributed another client sample in some strange language that is supposed to work well in browsers ;)

JavaScript client scenarios
There are two fundamental scenarios when it comes to JavaScript clients. The most common is probably that the JS code is originating from the same web application that also contains the web APIs. Think a web page that does some AJAX style callbacks to an API that belongs to that web app – Validation, data access etc. come to mind. Single page apps often fall in that category.

The good news here is that this scenario just works. The typical course of events is that the user first logs on to the web application – which will result in an authentication cookie of some sort. That cookie will get round-tripped with your AJAX calls and ASP.NET does its magic to establish a client identity context. Since WebAPI inherits the security context from its (web) host, the client identity is also available here.

The other fundamental scenario is JavaScript code *not* running in the context of the WebAPI hosting application. This is more or less just like a normal desktop client – either running in the browser, or if you think of Windows 8 Metro style apps as “real” desktop apps. In that scenario we do exactly the same as the samples did in my last post – obtain a token, then use it to call the service.

Obtaining a token from IdentityServer’s resource owner credential OAuth2 endpoint could look like this:

thinktectureIdentityModel.BrokeredAuthentication
= function (stsEndpointAddress,
scope) {
   
this
.stsEndpointAddress = stsEndpointAddress;
   
this
.scope = scope;
};

thinktectureIdentityModel.BrokeredAuthentication.prototype =
function
() {
    getIdpToken =
function
(un, pw, callback) {
        $.ajax({
            type:
'POST'
,
            cache:
false
,
            url:
this
.stsEndpointAddress,
            data: { grant_type:
"password", username: un, password: pw, scope: this
.scope },
            success:
function
(result) {
                callback(result.access_token);
            },
            error:
function
(error) {
               
if
(error.status == 401) {
                    alert(
'Unauthorized'
);
                }
               
else
{
                    alert(
'Error calling STS: '
+ error.responseText);
                }
            }
        });
    };

    createAuthenticationHeader =
function
(token) {
       
var tok = 'IdSrv '
+ token;

       
return
tok;
    };

   
return {
        getIdpToken: getIdpToken,
        createAuthenticationHeader: createAuthenticationHeader
    };
} ();

Calling the service with the requested token could look like this:

function getIdentityClaimsFromService()
{
    authHeader = authN.createAuthenticationHeader(token);

    $.ajax({
        type:
'GET'
,
        cache:
false
,
        url: serviceEndpoint,
        beforeSend:
function
(req) {
            req.setRequestHeader(
'Authorization'
, authHeader);
        },
        success:
function
(result) {
             $.each(result.Claims, function (key, val) {
                $(
'#claims').append($('<li>' + val.Value + '</li>'
))
            });
        },
        error:
function
(error) {
            alert(
'Error: ' + error.responseText);
        }
    });

I updated the github repository, you can can play around with the code yourself.

© Least Privilege or respective owner

Related posts about IdentityModel

Related posts about WebAPI