Federated Logout with the Katana WS-Federation Middleware

For some reason the Katana WS-Fed middleware does not seem to implement signout cleanup.

This means that your application will ignore federated signout callbacks from the STS which will result in resources like logon cookies not being cleaned up properly.

Here’s a quick fix for your pipeline:

app.Use(async (ctx, next) =>
{
   
var
qs = ctx.Request.Query;
   
var wa = qs.Get("wa"
);

   
if (wa != null
)
    {
       
if (wa == "wsignoutcleanup1.0"
)
        {
           
// clean up resources, e.g. the logon cookie

            ctx.Authentication.SignOut(
"Cookies"
);
        }
    }

   
await next();
});

HTH

Posted in .NET Security, ASP.NET, Katana, OWIN | Leave a comment

Security at NDC Oslo

For a developer conference, NDC Oslo had a really strong security track this year. Also the audience appreciated that – from the five highest ranked talks – three were about security. Troy has the proof.

I even got to see Bruce Schneier for the first time. It is fair to say that his “Secrets & Lies” book changed my life and was one of the major reasons I got interested in security (besides Enno).

Brock and I did a two day workshop on securing modern web applications and APIs followed by a talk on Web API security patterns and how to implement authentication and authorization in JavaScript applications.

Other talks worth watching (I hope I haven’t missed anything):

Well done, NDC!

Posted in .NET Security, IdentityModel, IdentityServer, OAuth, OpenID Connect, WebAPI | Leave a comment

Give your WCF Security Architecture a Makeover with IdentityServer3

Not everybody has the luxury of being able to start over and build the new & modern version of their software from scratch. Many people I speak to have existing investments in WCF and their “old-school” desktop/intranet architecture.

Moving to an internet/mobile world while preserving the existing services is not easy because the technologies (and in my case the security technologies) are fundamentally incompatible. Your new mobile/modern clients will not be seamlessly able to request tokens from your existing WS-Trust STS and SOAP is not really compatible with OAuth2. So what to do?

You could try to teach your WS-Trust STS some basic HTTP based token service capabilities and continue using SAML tokens. You could provide some sort of SAML/JWT conversion mechanism and create Web APIs for your new clients that proxy / convert to the WCF world. Or you could provide to separate token services and establish trust between them. All approaches have their own advantages and disadvantages.

For a project I am currently working on I chose a different approach – get rid of the old WS-Trust STS altogether, replace it with an OAuth2 authorization server (IdentityServer3) and make your WCF services consume JWT tokens. This way both old and new clients can request tokens via OAuth2 and use them with either existing WCF services and the new Web APIs (which ultimately will be also used in the desktop version of the product). How does that work?

Requesting the token
The OAuth2 resource owner flow is what comes closest to WS-Trust and it is easy to replace the WCF WSTrustChannel code with that. Going forward the web view based flows actually give more features like external IdPs etc. but need a bit more restructuring of the existing clients. New clients can use them straight away.

Sending the token
This is the tricky part. WCF can not deal with JWTs directly since they are not XML based. You first need to wrap them in an XML data structure and the typical approach for that is to use a so called binary security token. This worked fine at some point but the latest version of WCF and the JWT token handler don’t seem to work together anymore (here’s a nice write up from Mickael describing the problem).

Since WCF is really done – I did not expect anyone to fix that bug anytime soon, so I needed a different solution.

Another XML container data structure that is well tested and does the job equally well is SAML – so I simply created a minimal SAML assertion to hold the JWT token.

static GenericXmlSecurityToken WrapJwt(string jwt)
{
   
var subject = new ClaimsIdentity("saml"
);
    subject.AddClaim(
new Claim("jwt"
, jwt));

   
var descriptor = new SecurityTokenDescriptor
    {
        TokenType =
TokenTypes
.Saml2TokenProfile11,
        TokenIssuerName =
"urn:wrappedjwt"
,
        Subject = subject
    };

   
var handler = new Saml2SecurityTokenHandler
();
   
var
token = handler.CreateToken(descriptor);

   
var xmlToken = new GenericXmlSecurityToken
(
      
XElement
.Parse(token.ToTokenXmlString()).ToXmlElement(),
       
null
,
       
DateTime
.Now,
       
DateTime
.Now.AddHours(1),
       
null
,
       
null
,
       
null
);

   
return xmlToken;
}

Since we are using SAML solely as a container, there is no signature, no audience URI and just a single attribute statement containing the JWT.

After that you can use the wrapped JWT with the CreateChannelWithIssuedToken method over a federation binding:

var binding = new WS2007FederationHttpBinding(
WSFederationHttpSecurityMode
.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuedKeyType =
SecurityKeyType
.BearerKey;
var factory = new ChannelFactory<IService
>(
    binding,
   
new EndpointAddress(https://localhost:44335/token
));

var channel = factory.CreateChannelWithIssuedToken(xmlToken);

Validating the token
On the service side I sub-classed the SAML2 security token handler to get the SAML deserialization. In the ValidateToken method I retrieve the JWT token from the assertion and validate it.

Since I have to do the validation manually anyways, I wanted feature parity with our token validation middleware for Web API which means that the token handler can auto-configure itself using the OpenID Connect discovery document as well as do the scope validation.

identityConfiguration.SecurityTokenHandlers.Add(
new IdentityServerWrappedJwtHandler("https://localhost:44333/core", "write"));

The end result is that both WCF and Web API can now consumes JWT tokens from IdentityServer and the customer can smoothly migrate and extend their architecture.

The POC can be found here. It is “sample quality” right now – feel free to make it more robust and send me a PR.

Posted in .NET Security, IdentityServer, OAuth, WCF, WebAPI | 13 Comments

Three days of Identity & Access Control Workshop at SDD Deep Dive – November 2015, London

As part of the SDD Deep Dive event in London – Brock and I will deliver an updated version of our “Identity & Access Control for modern Web Applications and APIs” workshop.

For the first time, this will be a three day version covering everything you need to know to implement authentication & authorization in your ASP.NET web applications and APIs.

The additional third day will focus on IdentityServer3 internals and customization as well as an outlook on how to migrate your security architecture to ASP.NET 5 and MVC6.

Come by and say hello! (also get some of our rare IdentityServer stickers)

http://sddconf.com/identityandaccess/

Posted in .NET Security, IdentityServer, Katana, OAuth, OpenID Connect, OWIN, WebAPI | Leave a comment

OpenID Connect Certification for IdentityServer3

I am extremely happy to announce that IdentityServer3 is now officially certified by the OpenID Foundation.

OpenID_Certified

http://openid.net/certification/

Version 1.6 and onwards is now fully compatible with the basic, implicit, hybrid and configuration profile of OpenID Connect.

Posted in .NET Security, ASP.NET, IdentityServer, Katana, OAuth, OpenID Connect, OWIN, WebAPI | 2 Comments

Implicit vs Explicit Authentication in Browser-based Applications

I got the idea for this post from my good friend Pedro Felix – I hope I don’t steal his thunder (I am sure I won’t – since he is much more elaborate than I am) – but when I saw his tweet this morning, I had to write this post.

When teaching web API security, Brock and I often use the term implicit vs explicit authentication. I don’t think these are standard terms – so here’s the explanation.

What’s implicit authentication?
Browser built-in mechanisms like Basic, Windows, Digest authentication, client certificates and cookies. Once established for a certain domain, the browser implicitly sends the credential along automatically.

Advantage: It just works. Once the browser has authenticated the user (or the cookie is set) – no special code is necessary

Disadvantage:

  • No control. The browser will send the credential regardless which application makes the request to the “authenticated domain”. CSRF is the result of that.
  • Domain bound – only “clients” from the same domain as the “server” will be able to communicate.

What’s explicit authentication?
Whenever the application code (JavaScript in that case) has to send the credential explicitly – typically on the Authorization header (and sometimes also as a query string). Using OAuth 2.0 implicit flow and access tokens in JS apps is a common example. Strictly speaking the browser does not know anything about the credential and thus would not send it automatically.

Advantage:

  • Full control over when the credential is send.
  • No CSRF.
  • Not bound to a domain.

Disadvantages:

  • Custom code necessary.
  • Access tokens need to be managed by the JS app (and don’t have built-in protection features like httpOnly cookies) which make them interesting targets for other types of attacks (CSP can help here).

Summary: Implicit authentication works great for server-side web applications that live on a single domain. CSRF is well understood and frameworks typically have built-in countermeasures. Explicit authentication is recommended for web APIs. Anti CSRF is harder here, and clients and APIs are often spread across domains which makes cookies a no go.

Posted in WebAPI | 2 Comments

IdentityServer3 vNext

Just a quick update about some upcoming changes in IdentityServer3.

The last weeks since the 1.0.0 release in January we did mostly bug fixing, fine tuning and listening to feedback. Inevitably we found things we want to change and improve – and some of them are breaking changes.

Right now we are in the process of compiling these small and big changes to bundle them up in a 2.0.0 release, so hopefully after that we can go back into fine tuning mode without breaking anybody’s code.

Here’s a brief list of things that have/will change in 2.0.0

  • Consolidation of some validation infrastructure
    • ICustomRequestValidator signature has slightly changed
  • Support for X.509 client certificates for client authentication at the token endpoint. This resulted in a number of changes to make client validation more flexible in general
    • ClientSecret has been renamed to Secret (we will probably use the concept of secrets in more place than just the client in the future)
    • IClientSecretValidator is gone in favour of a more high level IClientValidator
  • The event service is now async (we simply missed that in 1.0)
  • The CorsPolicy has been replaced by a CORS policy service – along with configurable CORS origins per client
  • By default clients have no access to any scopes. You need to configure the allowed scopes (or override by setting the new AllowAccessToAllScopes client flag)

Probable the biggest change is the fact that we renamed the nuget package to simply IdentityServer3. We decided to remove the thinktecture registered trademark from the OSS project altogether (including the namespaces – so that’s another breaking change).

So in the future all you need to do is:

install-package IdentityServer3 (-pre for the time being)

The dev branch on github is now on 2.0.0 and we published a beta package to nuget so you can have a look (in addition to our myget dev feed):

https://www.nuget.org/packages/IdentityServer3/2.0.0-beta1

Feedback is welcome!

Posted in .NET Security, ASP.NET, IdentityServer, OAuth, OpenID Connect, OWIN, WebAPI | 1 Comment