IdentityModel: OpenID Connect & OAuth 2.0 Client Library for Mobile/Native Applications

Recently we had a couple of customers that needed to connect their native desktop and mobile applications to an OpenID Connect and OAuth 2.0 back-end.

We always had samples that showed how to do this, but making them re-usable and cross-platform was a bit harder than I originally thought. At the same time the IETF released some good guidance around OAuth 2.0 for native applications (draft-spec) that I wanted to incorporate.

The end result of that is IdentityModel.OidcClient, which is a PCL that runs on desktop .NET, WinRT/UWP and Xamarin iOS and Android. It encapsulates all the protocol and crypto work needed for OpenID Connect Hybrid Flow with PKCE and can reduce all those steps to a few lines of code:

var client = new OidcClient(options);
var result = await client.LoginAsync();

The result object will contain the claims of the user as well as an access token and refresh token (if requested).

The second problem I wanted to solve is keeping the access tokens fresh without putting too much logic into the client application. This is done by an HTTP message handler that you can plug into HttpClient. The handler will add the access token to outgoing requests and try to refresh the token whenever it sees a 401 response. You would then use this one HttpClient throughout your code:

_client = new HttpClient(result.Handler);
_client.BaseAddress = new Uri("https://demo.identityserver.io/api/");

You can find more code snippets in the readme and the samples repo contains sample WinForms, UWP and iOS clients.

OSS FTW
To create such a library as a PCL was a combined effort – I’d like to thank Andrew Arnott for PCLCrypto and dvsekhvalnov for building Jose-Pcl on top. Without them JWT validation wouldn’t be possible.

I pushed a 1.0 to nuget – but there is still a lot of work. I opened a couple of issues already which are all up for grabs.

We also need more samples – Android, WPF and console hosts come to mind. Please support OidcClient and the above libraries by giving feedback and maybe contributing to them.

HTH

 

Posted in IdentityModel, OAuth, OpenID Connect | 16 Comments

IdentityServer4 on ASP.NET Core RC2

This week was quite busy ;) Besides doing a couple of talks and workshops at SDD in London – we also updated all the IdentityServer4 bits to RC2.

Many thanks to all the people in the community that were part of this effort!

Here are the relevant links:

IdentityServer4 repo / nuget
AccessTokenValidation repo / nuget
Samples repo

Now that RC2 is finally released, we will continue our work on IdentityServer4. Expect more changes and frequent updates soon. stay tuned!

Posted in ASP.NET, IdentityServer, OAuth, OpenID Connect, WebAPI | 9 Comments

NDC London 2016 Wrap-up

NDC has been fantastic again! Good fun, good talks and good company!

Brock and I did the usual 2-day version of our Identity & Access Control workshop at the pre-con. This was (probably) the last time we ran the 2-day version on Katana. At NDC in Oslo it will be all new material based on ASP.NET Core 1.0 (fingers crossed ;))

The main conference had dozens of interesting sessions and as always – pretty strong security content. On Wednesday I did a talk on (mostly) the new identity & authentication features of ASP.NET Core 1.0 [1]. This was also the perfect occasion to world-premier IdentityServer4 – the preview of the new version of IdentityServer for ASP.NET and .NET Core [2].

Right after my session, Barry focused on the new data protection and authorization APIs [3] and Brock did an introduction to IdentityServer (which is now finally on video [4]).

We also did a .NET Rocks [5] and Channel9 [6] interview – and our usual “user group meeting” at Brewdogs [7] ;)

All in all a really busy week – but well worth it!

[1] What’s new in Security in ASP.NET Core 1.0
[2] Announcing IdentityServer4
[3] A run around the new Data Protection and Authorization Stacks
[4] Introduction to IdentityServer
[5] .NET Rocks
[6] Channel9 Interview
[7] Brewdog Shepherd’s Bush

 

Posted in .NET Security, ASP.NET, IdentityServer, OAuth, OpenID Connect, Uncategorized, WebAPI | 9 Comments

PKCE Support in IdentityServer and IdentityModel

PKCE stands for “Proof Key for Code Exchange” and is a way to make OAuth 2.0 and OpenID Connect operations using an authorization code more secure. It is specified in RFC 7636.

PKCE applies to authorization/token requests whenever the code grant type is involved – e.g. plain OAuth 2.0 authorization code flow as well as (the superior) OpenID Connect hybrid flow (e.g. code id_token).

It mitigates an attack where the authorization response can be intercepted and the “stolen” code can be used to request access tokens. It introduces a per-request secret between the legitimate client and the authorization server, that is unknown to an attacker that can only see authorization responses. This is mainly useful for mobile/native clients.

IdentityServer3 as of v2.4 fully supports PKCE and the authorization and token endpoint documentation has the new parameters. Also the discovery endpoint now includes the code_challenge_methods_supported entry.

IdentityModel v1.5 includes the client pieces to interact with PKCE. You can e.g. use the following code to construct an authorization request:

var nonce = CryptoRandom.CreateRandomKeyString(64);
var verifier = CryptoRandom.CreateRandomKeyString(64);
var challenge = verifier.ToCodeChallenge();
 
var request = new AuthorizeRequest("https://my.server/authorization");
var url = request.CreateAuthorizeUrl(
    clientId: "myclient",
    responseType: "code id_token",
    scope: "openid myapi",
    redirectUri: "https://my.client/cb",
    nonce: nonce,
    codeChallenge: challenge,
    codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256);

and the TokenClient to exchange the code with the token:

var tokenClient = new TokenClient(
    "https://my.server/token",
    "client",
    "secret");
 
var response = await tokenClient.RequestAuthorizationCodeAsync(
    code: code,
    redirectUri: "https://my.client/cb",
    codeVerifier: verifier);
Posted in IdentityServer, OAuth, OpenID Connect, Uncategorized | 4 Comments

Which OpenID Connect/OAuth 2.0 Flow is the right One?

That is probably the most common question we get – and the answer is of course: it depends!

Machine to Machine Communication
This one is easy – since there is no human directly involved, client credentials are used to request tokens.

Browser-based Applications
This might be a JavaScript-based application or a “traditional” server-rendered web application. For those scenarios, you typically want to use the implicit flow (OpenID Connect / OAuth 2.0).

A side effect of the implicit flow is, that all tokens (identity and access tokens) are delivered through the browser front-channel. If you want to use the access token purely on the server side, this would result in an unnecessary exposure of the token to the client. In that case I would prefer the authorization code flow – or hybrid flow.

Native Applications
Strictly speaking, a native application has very similar security properties compared to a JavaScript application. Still they are generally considered a bit more easy to secure because you often have stronger platform support for protecting data and isolation.

That’s the reason why the current consensus is, that an authorization code based flow gives you “a bit more” security than implicit. The much more important reason IMO is, that there are a couple of (upcoming) protocols that are optimized for native clients, and they use code exchange and the token endpoint as a foundation – e.g. PKCE, Proof of Possession and AC/DC.

Remark 1: With native applications I mean applications that have access to platform-native APIs like data protection or maybe the system browser. Cordova applications are e.g. written in JavaScript, but I would not consider them to be a “browser-based application”.

Remark 2: For code based flows, you need to embed the client secret in the client application. Of course you can’t treat that as a secret anymore – no matter how good you protect it, a motivated attacker will be able to reverse engineer it. It is still a bit better than no secret at all. Specs like PKCE make it a bit better as well.

Remark 3: I often hear the argument that the client application does not care who the user is, it just needs an access token – thus we rather do OAuth 2.0 than OpenID Connect. While this might be strictly speaking true – OIDC is the superior protocol as it includes a couple of extra security features like nonces for replay protection or c_hash and at_hash to link the (verifiable) identity token to the (unverifiable) access token.

Remark 4: As an extension to remark 3 – always use OpenID Connect – and not OAuth 2.0 on its own. There should be client libraries for every platform of interest by now. ASP.NET has middleware, we have a library for JavaScript. Other platforms should be fine as as well.

Remark 5: Whenever you think about using authorization code flow – rather use hybrid flow. This gives you a verifiable token first before you make additional roundtrips (another extensions of remark 3 and 4).

HTH

Posted in .NET Security, IdentityServer, OAuth, OpenID Connect, WebAPI | 21 Comments

Announcing IdentityServer for ASP.NET 5 and .NET Core

Over the last couple of years, we’ve been working with the ASP.NET team on the authentication and authorization story for Web API, Katana and ASP.NET 5. This included the design around claims-based identity, authorization and token-based authentication.

In the Katana timeframe we also reviewed the OAuth 2.0 authorization server middleware (and the templates around it) and weren’t very happy with it. But as usual, there were deadlines and Web API needed a token-based security story, so it shipped the way it was.

One year ago the ASP.NET team decided to discontinue that middleware and rather focus on consuming tokens instead. They also asked us if IdentityServer can be the replacement going forward.

By that time there were many unknowns – ASP.NET was still in early betas and literally changing every day. Important features like x-plat crypto (and thus support for JWT) weren’t even existing. Nevertheless, we agreed that we will port IdentityServer to ASP.NET 5 and .NET Core once the builds are more stabilized.

With RC1 (and soon RC2), we decided that now would the right moment in time to start porting IdentityServer – and here it is: IdentityServer4 (github / nuget / samples)

What’s new
When we designed IdentityServer3, one of our main goals was to be able to run self-hosted. At that time MVC was tied to IIS so using it for our default views was not an option. We weren’t particularly keen on creating our own view engine/abstraction, but that’s what needed to be done. This is not an issue anymore in ASP.NET 5, and as a result we removed the view service from IdentityServer4.

In IdentityServer4 you have full control over all UI aspects – login, consent, logoff and any additional UI you want to show to your user. You also have full control over the technology you want to use to implement that UI – it will be even possible to implement the UI in a completely different web application. This would allow adding OAuth 2.0 / OpenID Connect capabilities to an existing or legacy login “application”.

There will be also a standard UI that you can simply add as a package as well as templates to get you started.

Furthermore, IdentityServer4 is a “real” ASP.NET 5 application using all the standard platform facilities like DI, Logging, configuration, data protection etc, which means you have to learn less IdentityServer specifics.

What’s not new
Everything else really – IdentityServer4 has (or will have) all the features of IdentityServer3. You still can connect to arbitrary user management back-ends and there will be out of the box support for ASP.NET Identity 3.

We still provide the same architecture focused modelling around users, clients and scopes and still shield you from the low level details to make sure no security holes are introduced.

Database artifacts like reference or refresh tokens are compatible which gives you a nice upgrade/migration story.

Next steps
We will not abandon IdentityServer3 – many people are successfully using it and are happy with it (so are we). We are also aware that not everybody wants to switch its identity platform to “the latest thing” but rather wait a little longer.

But we should also not forget that IdentityServer3 is built on a platform (Katana) which Microsoft is not investing in anymore – and that also applies to the authentication middleware we use to connect to external providers. ASP.NET 5 is the way forward.

We just published beta1 to nuget. There are still many things missing, and what’s there might change. We also started publishing samples (link) to showcase the various features. Please try them out, give us feedback, open issues.

Around the RC2 timeframe there will be also more documentation showing up in our docs as and the ASP.NET documentation site. At some point, there will be also templates for Visual Studio which will provide a starting point for common security scenarios.

IdentityServer3 was such a great success because of all the good community feedback and contributions. Let’s take this to the next level!

Posted in ASP.NET, IdentityServer, OAuth, OpenID Connect, Uncategorized, WebAPI | 77 Comments

Validating Scopes in ASP.NET 4 and 5

OAuth 2.0 scopes are a way to model (API) resources. This allows you to give logical “names” to APIs that clients can use to request tokens for.

You might have very granular scopes like e.g. api1 & api2, or very coarse grained like application.backend. Some people use functional names e.g. contacts.api and customers.api (which might or might not span multiple physical APIs) – some group by criteria like public or internal only. Some even sub-divide a single API – e.g. calendar.read and calendar.readwrite. It is totally up to you (this is how Google uses scopes).

At the end of the day, the access token (be it self-contained or referenced) will be associated with the scopes the client was authorized for (and optionally – the user consented to).

IdentityServer does that by including claims of type scope in the access token – so really any technique that allows checking the claims of the current user will do.

As a side note – there is also a spec that deals with return codes for failed scope validation. In short – this should return a 403 instead of a 401.

We ourselves had some iterations in our thinking how we deal with scopes – here’s a summary and some options.

ASP.NET 4.x

The most common way we do scope checking is via our token validation middleware (source/nuget), which combines token and scope validation into a single step:

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
    {
        Authority = "https://localhost:44333/core",
        RequiredScopes = new[] { "calendar.read""calendar.readwrite" },
    });

This would validate the token and require that either the calendar.read or calendar.readwrite scope claims are present.

This middleware also emits the right response status code, Www-Authenticate header and respects CORS pre-flight requests.

For finer granularity we also once wrote a Web API authorization attribute – [ScopeAuthorize] that you can put on top of controllers and actions (source).

As mentioned before – you can always check inside your code for scope claims yourself using the claims collection.

ASP.NET 5

We will have the same “all in one” IdentityServer token validation middleware for ASP.NET 5 – but this time split up into separate middleware that can be also used stand-alone (I wrote about the introspection aspect of it in my last post).

The scope validation part (source/nuget) of it looks like this:

app.AllowScopes("calendar.read""calendar.readwrite");

This has the same OR semantics as described above.

You can also use the new ASP.NET 5 authorization API to do scope checks – e.g. as a global policy:

public void ConfigureServices(IServiceCollection services)
{
    var scopePolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .RequireClaim("scope""calendar.read""calendar.readwrite")
        .Build();
 
    services.AddMvc(options =>
    {
        options.Filters.Add(new AuthorizeFilter(scopePolicy));
    });
}

..or as a named policy to decorate individual controllers and actions:

services.AddAuthorization(options =>
{
    options.AddPolicy("read",
        policy => policy.RequireClaim("scope""calendar.read"));
    options.AddPolicy("readwrite",
        policy => policy.RequireClaim("scope""calendar.readwrite"));
});

and use it e.g. like that:

public class CalendarControllerController
{
    [Authorize("read")]
    public IActionFilter Get() { ... }
 
    [Authorize("readwrite")]
    public IActionFilter Put() { ... }
}

One last remark: We get this question a lot – scopes are not used for authorizing users. They are used for modeling resources (and optionally to compose the consent screen as well as to specify which client might have access to these resources).

HTH

Posted in ASP.NET, IdentityModel, IdentityServer, Katana, OAuth, Uncategorized, WebAPI | 10 Comments