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.
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
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.
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?
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.
Hi!
The link to GitHub repository is broken.
Cloud you check it?
Thanks
https://github.com/thinktecture/Thinktecture.IdentityModel.45/tree/master/Samples/Web%20API%20Security