Demos — 6th Annual Hartford Code Camp 2013
Demos and slides for my sessions are here.
Links for topics I mentioned:
- DevelopMentor classroom training
- DevelopMentor online training
- Thinktecture IdentityModel security library
- Thinktecture IdentityServer Identity Provider/STS
Thanks for coming.
In ASP.NET WebAPI (with its recent OData additions) there is good support for HTTP PATCH requests via the Delta<T> class. I won’t bother reproducing a tutorial here since there’s already a good one online.
The only problem with the PATCH support and tutorial is that there is no guidance on how to validate the model once you’ve accepted the partially updated data. So here’s what I came up with to validate the model once we’ve called Patch:
public HttpResponseMessage Patch(Guid id, Delta<TenantData> data)
{
var tenant = this.TenantRepository.Get(id);
if (tenant == null) return Request.CreateResponse(HttpStatusCode.NotFound);
data.Patch(tenant);
// this is where we do the validation on the model after we've
// merged in the patch values
var svc = this.Configuration.Services;
var validator = svc.GetBodyModelValidator();
var ad = svc.GetActionSelector().SelectAction(this.ControllerContext);
var ac = new HttpActionContext(this.ControllerContext, ad);
var mp = svc.GetModelMetadataProvider();
if (!validator.Validate(tenant, typeof(TenantData), mp, ac, "data"))
{
// validation failed, so return our error and pass along the
// ModelState from the action context (which is a different
// instance than this.ModelState)
return Request.CreateErrorResponse(HttpStatusCode.BadRequest,
ac.ModelState);
}
this.TenantRepository.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK, tenant);
}
In essence, I needed to manually trigger validation that normally happens during model binding. I wish there was a nice API built-in for this, but alas there is not.
6th Annual Hartford Code Camp 2013
I’ll be speaking at the 6th Annual Hartford Code Camp on May 18th, 2013. I’ll be presenting two topics: one on Claims-based Security with Windows Identity Foundation and another on Securing ASP.NET WebAPI Services. Hope to see you there!
Getting JSON web tokens (JWTs) from ADFS via Thinktecture IdentityServer’s ADFS Integration
Dominick and I recently added three features to IdentityServer that collectively we call “ADFS Integration”. This “ADFS Integration” is a new protocol (which can be enabled, disabled and configured like any other protocol IdentityServer supports). In short this new protocol helps obtain JWTs (indirectly) from ADFS (or really any WS-Trust enabled STS). I’ll describe the three use cases here and how we provide a solution for each:
Scenario #1 — Converting SAML to JWT for delegation-like use:
Imagine you’re building a website that authenticates users by accepting SAML tokens from an ADFS STS that your app trusts (standard WS-Fed). Your app then wants to invoke a WebAPI using the end-user’s identity (a delegation-like scenario). The WebAPI trusts ADFS and wants to leverage all the features of ADFS in producing the token for the WebAPI (such as the authorization rules, claims issuance rules, etc.), but the WebAPI only wants to accept JWTs. How does your web app get a JWT from ADFS for the WebAPI?
If the WebAPI accepted SAML tokens, then this wouldn’t be a problem — the web app would just use WS-Trust and obtain a delegation token directly from ADFS for the WebAPI. But the main obstacle is the JWT requirement.
Solution #1 — IdentityServer’s ADFS SAML authentication:
IdentityServer now supports a new ADFS integration endpoint which can be used to obtain a JWT from a SAML token. For the above scenario, the web application would need to preserve the original SAML token via WIF’s “maintain bootstrap token option”. The web app would then contact the ADFS integration endpoint in IdentityServer passing the SAML token and the realm for which it requires a delegation token (this would be the realm identifier for the WebAPI). IdentityServer would then do the necessary calls to ADFS to obtain a new SAML token for the WebAPI and then IdentityServer will finally convert the SAML token into a JWT and return it to the web application. The web application can then use that as the token when invoking the WebAPI.
For this magic to happen, there is some configuration required in ADFS. First, IdentityServer needs to be configured as a claims provider trust. Second, the WebAPI needs to be configured as a relying party. But with those two configuration settings (and any other rules related to authorization and claims desired) you are really just using the normal features of ADFS to create the token for the WebAPI.
As far as implementation details, essentially IdentityServer is using the bootstrap token to create its own token for the user (as a claims provider trust). It then calls the normal WS-Trust federation endpoints to have ADFS create a token for the WebAPI RP using the token from IdentityServer as the authentication mechanism. So, this isn’t truly creating a delegation token in the sense that the delegation chain is maintained, but the token can be used like a delegation token to pass the end-user’s identity to downstream relying parties.
The configuration needed in IdentityServer for this solution looks as follows:
- Enable the ADFS Integration protocol
- Enable the SAML authentication option
- Indicate a token lifetime
- Disable the Pass-thru authentication token option (otherwise SAML will be returned not JWT)
- Indicate the ADFS federation endpoint (the mixed/symmetric/basic256 WS-Trust endpoint)
- Indicate the ADFS identifier
- Indicate the ADFS signing certificate thumbprint
- Indicate the ADFS encryption certificate
Scenario #2 –Converting JWT to JWT for delegation-like use:
Now imagine you’re building the WebAPI application being invoked from the web app mentioned above. You’ve received a JWT that authenticates the user (and it’s audience is for your application), but you then want to invoke a second WebAPI delegating the user’s identity. We have almost the same problem as above – the second WebAPI wants ADFS to produce the token but wants it in JWT form. The only difference in this scenario is that the app has a JWT for the user and not a SAML token.
Solution #2 — IdentityServer’s ADFS JWT authentication:
The solution here is almost identical to the solution above. The ADFS integration endpoint can accept a SAML token (as described above) but it will also accept a JWT. So really this one endpoint solves both scenario #1 and scenario #2.
In IdentityServer the same configuration would be needed as above, except you would also need to enabled the “Enable JWT authentication” option.
Scenario #3 — Obtaining JWT for AD users from a native/mobile app:
Imagine you’re building a native mobile application (iOS, Android, etc.) for your company and it needs to invoke a WebAPI with the user’s identity. Same as above, the WebAPI want ADFS to produce the token but wants it in JWT form. These mobile platforms don’t have native AD authentication or WS-Trust libraries and yet need some means to authenticate the user and get a JWT for the WebAPI.
Solution #3 — IdentityServer’s ADFS password authentication:
The final credential type that the ADFS integration endpoint supports is username and password. The native application will collect the user’s credentials and, similar to the other two scenarios, it will pass to IdentityServer those credentials and the realm identifier for the WebAPI it wants to invoke. IdentityServer will contact ADFS and return a JWT to the native app. The native app can use that as the token when calling the WebAPI.
If this last scenario is all you needed, then the minimal configuration needed in IdentityServer would be this:
- Enable the ADFS Integration protocol
- Enable the password authentication option
- Indicate a token lifetime
- Disable the Pass-thru authentication token option (otherwise SAML will be returned not JWT)
- Indicate the ADFS username endpoint (the username/mixed WS-Trust endpoint)
- Indicate the ADFS signing certificate thumbprint
The one last thing I’ll say after this new ADFS integration feature — when IdentityServer converts a SAML token from ADFS into a JWT it is signing the JWT with its signing key. So this means that the signing thumbprint all the relying parties trust need to be that of IdentityServer. This might be different than the signing key of ADFS, or it could be the same — this configuration choice would be up to you. But this is a detail that is important to be aware of.
There are two samples that illustrate exercising these endpoints. First there’s a sample that just invokes the endpoints and second there’s a more full fledged sample that illustrates the real flow through the web application and then to two downstream relying party WebAPI apps.
Feedback welcome and enjoy!
CORS open source contribution to ASP.NET and System.Web.Cors
Dominick is the person who convinced me to build the CORS implementation in Thinktecture IdentityModel. I didn’t realize it would be used as much as it has. Given the popularity and the need for something built into ASP.NET (and specifically WebAPI), I submitted my CORS implementation as a contribution to the ASP.NET web stack. Microsoft accepted my contribution and I worked with them for a couple of weeks to rework the design for inclusion into the platform.
I’m happy to announce that today Microsoft (specifically Yao, who was a pleasure to work with) did the checkin into the master branch to support CORS in the ASP.NET web stack. This means we’ll have framework support for CORS in the next release of WebAPI. It also means that I get the honor and privilege to be listed as a contributor to ASP.NET.
Yao has already provided some initial documentation here.
Edit: Here’s the Channel9 interview related to this.
Thinktecture IdentityServer now supports localization
Thanks to the contribution by Sébastien and Bruno, IdentityServer now supports localization! They performed the work to allow localization and provided the default English and French translations. I just performed the merge today and it was a large one (467 changed files) which illustrates the effort they put into it. Merci!
If anyone else is interested in providing the translations to other languages, feel free to contact us and we can discuss!
Demos — DevWeek 2013
Despite being completely exhausted, I had a great time at my first DevWeek. It was great chatting with the attendees as well as the other speakers.
The sessions I presented were:
- Day-long pre-conference session: A day of jQuery and jQuery Mobile
- Async ASP.NET
- Internals of security in ASP.NET
- Mobile development with MVC 4 and jQuery Mobile
- Day-long post-conference session: A day of identity and access control for .NET 4.5 (co-speaking with Dominick)
The demos for the talks are located here. Also, links to the various open source projects mentioned are:
Many thanks to all for a great week.


