ASP.NET WebAPI Security 5: JavaScript Clients

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.

This entry was posted in IdentityModel, WebAPI. Bookmark the permalink.

6 Responses to ASP.NET WebAPI Security 5: JavaScript Clients

  1. markgmarkg says:

    Hi,

    My MVC 4 App is configured against Identity Server, and everything wokrs fine.

    Now we added WEB API (as separate application), and configured AuthenticationHandler to handle Identity Server SAML (same issuer, same realm and etc. as MVC 4 App). Desktop client works succesfully with WEB API.

    However, we fail to integrate MVC App with WEB Api – we use HttpClient to perform a call from MVC App to WEB Api.

    What is a right way to pass “claims” of already authenticated request to Web API?
    Should we try to convert “claimsset” to SAML, and then call WEB API?

    Thank you

  2. Hi,

    well you could either create your own token that represents the client in the MVC app and use that to authenticate with Web API.

    Or – use the bootstrap context (ClaimsIdentity.BootstrapContext) to forward the token to Web API.

    Both have their ups and downs. Give it a try.

  3. markgmarkg says:

    Dominick,

    The “Bootstrap” direction looks very promising :)

    I get Saml2SecurityToken from the bootstrap context, and the only obstacle I see here is a creation of “AuthenticationHeaderValue” when setting “DefaultRequestHeaders.Authorization” of “HttpClient” that calls web api:
    It looks like we can’t cast Saml2SecurityToken to GenericXmlSecurityToken, and then extract TokenXml.

    What might be an alternative to “forward” Saml2SecurityToken to Web Api?

  4. You can use the Saml2SecurityTokenHandler.WriteToken method to serialize to an XmlReader and from there to a string. Have a look at the extension methods in Thinktecture.IdentityModel – IIRC this is already imlemented there.

  5. Hi!
    The link to GitHub repository is broken.
    Cloud you check it?

    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s