MVP Summit Hackathon: IdentityServer v3 on ASP.NET vNext

Today we had a chance to sit together with the ASP.NET team and try moving IdentityServer to vNext.

There are two fundamental approaches for doing that – migrate the code and middleware to the new APIs or host IdentityServer as-is as an OWIN component.

We went for the latter – and lo and behold – after two hours we got everything up and running. Big thanks to Chris, Lou and Dan from the ASP.NET team!

This allows us (at least for the time being) to run IdentityServer on both ASP.NET vCurrent as well as vNext. This will not give us support for the new CoreCLR – but we also have a plan how to tackle that.

If you want to try it out yourself – the code can be found here.

2014-11-06 12.04.53

Update: two hours later, Christian got everything also running on Ubuntu!

leastprivilege_2014-Nov.-06

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

IdentityServer v3 Beta 3

Some of our users already found out and broke the news – so here’s my official post ;)

Beta 3 has been released to github and nuget – 107 commits since Beta 2-1…new features include:

  • Anti-forgery token support
  • Permission self-service page for users
  • Added support to add all claims of a user to a token (and support for implementation specific claims rules)
  • Added more documentation and comments
  • Added token handle and authorization code hashing
  • New view system and support for file system based assets
  • Support for WS-Federation, OpenID Connect and social external IdPs
  • Support for upstream federated sign-out
  • Added flag to hide scopes from discovery document
  • Re-worked claims filtering and normalization
  • Added support for more authentication scenarios, e.g. client certificates

Documentation will be updated, and new samples will be added ASAP – bear with us.

Again a massive thanks to all contributors and the people giving feedback and filing issues – you make IdentityServer better every day!

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

IdentityServer v3 and “Post Logout Redirect”

One frequently requested feature was the ability to redirect back to the client after logging out of IdentityServer. The session management spec describes this in the “RP-initiated logout” section.

While this is a nice convenience feature and seems trivial to implement, there are some security concerns around the validation of the URL to redirect to after logout is done. This feature could be abused for phishing.

The client first has to prove that it is a legitimate client by sending the original identity token that it received back to the logout endpoint. Furthermore you can now register a list of valid redirect URIs for each client. The request looks like this:

/connect/endsession?
  id_token_hint=<original_id_token>&
  post_logout_redirect_uri=https://client.com&
  state=some_state

How do you preserve the id_token? You need to store it somehow – e.g. using in the authentication cookie during SecurityTokenValidated notification when using the Katana OIDC middleware. You can then use the RedirectToIdentityProvider notification to attach it back on logout:

RedirectToIdentityProvider = async n =>

    {

        // if signing out, add the id_token_hint

        if (n.ProtocolMessage.RequestType ==
             
OpenIdConnectRequestType
.LogoutRequest)

        {

            var idTokenHint =
              n.OwinContext.Authentication.User.FindFirst(
“id_token”
).Value;

            n.ProtocolMessage.IdTokenHint = idTokenHint;

        }

    }

 

There are various ways how you can specify the post logout redirect URI – through the above event handler, statically on the OpenIdConnectAuthenticationOptions, or via the RedirectUri property on the AuthenticationProperties when calling IAuthenticationManager.SignOut.

See this sample here. HTH.

Posted in Uncategorized | Leave a comment

IdentityServer v3 Beta 2-1

We just did a minor update to Beta 2.

Besides some smaller changes and bug fixes we now support redirecting back to a client after logout (very requested feature). I will write a blog post soon describing how it works.

Posted in IdentityServer, OAuth, OpenID Connect, WebAPI | Leave a comment

Getting started with IdentityServer v3

Last night I started working on a getting started tutorial for IdentityServer v3 – while writing it, it became clear, that a single walkthrough will definitely not be enough to show the various options you have – anyways I started with the canonical “authentication for MVC scenario”, and it is work in progress.

Watch this space:

https://github.com/thinktecture/Thinktecture.IdentityServer.v3/wiki

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

OpenID Connect Hybrid Flow and IdentityServer v3

One of the features we added in Beta 2 is support for hybrid flow (see spec).  What is hybrid flow – and why do I care?

Well – in a nutshell – OpenID Connect originally extended the two basic OAuth2 flows (or grants) called authorization code and implicit. Implicit allows requesting tokens without explicit client authentication (hence the name), but uses the redirect URI instead to verify client identity. Because of that, requesting long lived tokens like a refresh token is not allowed in that flow.

Authorization code flow on the other hand only returns a so called authorization code via the unauthenticated front channel, and requires client authentication using client id and secret (or some other mechanism) to retrieve the actual tokens (including a refresh token) via the back channel. This mechanism was originally designed for server-based applications only, since storing client secrets on a client device is questionable without the right security mechanisms in place.

Hybrid flow (as the name indicates) is a combination of the above two. It allows to request a combination of identity token, access token and code via the front channel using either a fragment encoded redirect (native and JS based clients) or a form post (server-based web applications). This enables e.g. scenarios where your client app can make immediate use of an identity token to get access to the user’s identity but also retrieve an authorization code that that can be used (e.g. by a back end service) to request a refresh token and thus gaining long lived access to resources.

Lastly, hybrid flow is the only flow supported by the Microsoft OpenID Connect authentication middleware (in combination with a form post response mode), and before we added support for hybrid flow to IdentityServer, interop was a bit complicated (see here).

Our samples repo has two clients using hybrid flow – native and web. Let’s have a look at the middleware based one.

You are using hybrid flow whenever you have a response type of code combined with some other response type, e.g. id_token or token (or both).

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions

    {

        ClientId = “katanaclient”,

        Authority = Constants.BaseAddress,

        RedirectUri = Constants.RedirectUri,

        PostLogoutRedirectUri = Constants.PostLogoutUri,

        ResponseType = “code id_token token”,

        Scope = “openid email profile read write offline_access”,

 

        SignInAsAuthenticationType = “Cookies”

    };

 

The scopes are a combination of identity scopes allowing us to retrieve user identity (email and profile), resource scopes for api access (read and write) and a request for a refresh token (offline_access).

After authentication (and consent), the middleware will validate the response and notify you when it has retrieved the authorization code from the callback form post. You then typically have a number of responsibilities, e.g.

  • Contact the userinfo endpoint to retrieve the claims about the user
  • Transform the claims to whatever format your application expects
  • Store the access token for later use (along with information about its lifetime)
  • Store the refresh token so you can refresh expired access tokens (if long lived access is needed)
  • Store the id_token if you need features at the OpenID Connect provider that requires id token hints (e.g. redirects after logging out)

In our sample, I first strip all the protocol related claims from the identity token:

// filter "protocol" claims
var claims = new List<Claim>(from c in n.AuthenticationTicket.Identity.Claims
                                where c.Type != "iss" &&
                                      c.Type != "aud" &&
                                      c.Type != "nbf" &&
                                      c.Type != "exp" &&
                                      c.Type != "iat" &&
                                      c.Type != "nonce" &&
                                      c.Type != "c_hash" &&
                                      c.Type != "at_hash"
                                select c);

 

…then get the user claims from the user info endpoint

// get userinfo data
var userInfoClient = new UserInfoClient(
    new Uri(Constants.UserInfoEndpoint),
    n.ProtocolMessage.AccessToken);
 
var userInfo = await userInfoClient.GetAsync();
userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2)));

 

…and retrieve a refresh token (and a fresh access token)

// get access and refresh token
var tokenClient = new OAuth2Client(
    new Uri(Constants.TokenEndpoint),
    "katanaclient",
    "secret");
 
var response = await tokenClient.RequestAuthorizationCodeAsync(
    n.Code, n.RedirectUri);

 

Then I combine all the claims together and store them in the authentication cookie:

claims.Add(new Claim("access_token", response.AccessToken));
claims.Add(new Claim("expires_at", 
    DateTime.Now.AddSeconds(response.ExpiresIn).ToLocalTime().ToString()));
claims.Add(new Claim("refresh_token", response.RefreshToken));
claims.Add(new Claim("id_token", n.ProtocolMessage.IdToken));
 
n.AuthenticationTicket = new AuthenticationTicket(
    new ClaimsIdentity(claims.Distinct(new ClaimComparer()), 
        n.AuthenticationTicket.Identity.AuthenticationType), 
        n.AuthenticationTicket.Properties);

 

You might not need all of the above steps, but this is how it generally works. HTH.

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

Identity & Access Control at NDC London 2014

The NDC Agenda is out now – and Brock and me will do a number of identity & access control related sessions.

Brock will talk about identity management in ASP.NET – which is a huge topic – so he split up his talk into two sessions. I will cover OpenID Connect and OAuth2 – and especially the combination of the two protocols. Looking forward to that!

In addition we will do a 2-day workshop on monday/tuesday titled: “Identity & Access Control for modern Web Applications & APIs” – this will be deep dive in all the things you need to know to implement authentication and authorization into modern distributed applications. See the agenda here.

Early bird ends on 15th October – would be cool to meet you there and talk about security!

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