8

Essentially, this is an update to this question from nearly two years ago answered very helpfully by @Pinpoint of AspNet.Security.OpenIdConnect.Server fame.

I'll just put the rant at the bottom for all who care to indulge themselves in the 4am blasphemes of a frustrated developer.

I am starting some new projects and for my own reasons I would like to use the latest versions of ASP.NET technologies (ASP.NET 5 vNext and MVC 6) to get going.

A very popular modern application architecture

  • Secure REST API using tokens
  • Support for individual logins
  • Support for social logins

Latest and greatest techy .NET stuff

Typically OAuth2 can be used for the authentication.

The Problem

ASP.NET used to support the creation of tokens with OAuth2, but it doesn't any more and isn't going to, and apparently it wasn't very good anyway. There is some help, but I'm still a little lost as to how to tie it in with ASP.NET Identity and the new Authorize attribute.

So onto my actual question.

Is there a sample anywhere on this wavy, windy, scary internet that demonstrates the following:

  • ASP.NET 5/MVC 6 based REST API, secured with ASP.NET Identity and OAuth2, with an AccountController merrily creating accounts and serving tokens for social logins or individual logins, with a lovely ASP.NET Identity user store to keep things tidy, password recovery and a range of the standard, modern account stuff, and authorisation screens to confirm permissions requests ("XXX would like to access your account, is this OK?" etc.)
  • (optionally) Client app (I don't care if it is WPF, Cordova, AngularJS, written in assembler or running on a ZX81 with Meccano automating the tests) that supports logging in, both socially and with individual accounts, to a REST API and gets a nice little token to fan in the air like a polaroid

I've found some things that are close, closer and so on. But none that match.

As far as I understand, I can't use ASP.NET 5's new policy based authorisation stuff with IdentityServer3. I can't be the only human wanting this architecture, has someone accomplished this?

I feel like each time I come to secure my app, I'm inventing the wheel a little.

Rant

I have been away from authorisation stuff for over a year, but I've come back in and boy things have changed. And it's all rather confusing with OWIN, Katana, ASP.NET Identity, IdentityServer3, AspNet.Security.OpenIdConnect.Server. It seems there are only (albeit very excellent) side projects to fully support having a .NET based secure token server. By "side projects", I mean no offence to these great projects, only that there is nothing Microsoft and/or paid supported.

I want to get going with a whole load of development, but I am always stalled at the implementation of authentication in what I can't imagine is an unpopular architecture.

It seems so incredible to me that such a standard architectural scenario is so deftly considered by Microsoft.

When I want to implement logins in my REST app, I find myself upside-down and inside-out in a confusingly loud orchestra of cross firing information.

If anyone would like to start a maintained, open source template solution, let me know. I'm fed up of the start of building REST, token based apps being so unnecessarily complex for something so basically standard.

Community
  • 1
  • 1
joshcomley
  • 28,099
  • 24
  • 107
  • 147

1 Answers1

5

Is there a sample anywhere on this wavy, windy, scary internet that demonstrates the following:

ASP.NET 5/MVC 6 based REST API, secured with ASP.NET Identity and OAuth2, with an AccountController merrily creating accounts and serving tokens for social logins or individual logins, with a lovely ASP.NET Identity user store to keep things tidy, password recovery and a range of the standard, modern account stuff, and authorisation screens to confirm permissions requests ("XXX would like to access your account, is this OK?" etc.)

I'm currently working on a whole new identity server named OpenIddict: it's based on ASP.NET Identity 3 (that comes with ASP.NET 5) and uses AspNet.Security.OpenIdConnect.Server internally to control the entire OIDC flow. It's meant to offer the easiest way to get started with token authentication and it's compatible with both the full .NET framework and the new .NET Core.

Of course, it's neither developed nor founded by Microsoft (feel free to suggest them to support us), but it corresponds to your requirements: it comes with an internal controller that controls the authorization experience (i.e the consent form part) and relies on the AccountController you add to your application to handle the local/external authentication process.

It's still at the early stages and you need the ASP.NET 5/DNX RC2 nightly builds to use it, but it's quite easy to configure. You just need to call AddOpenIddict() from ConfigureServices and add UseOpenIddict() from Configure. You can find more information on the GitHub repository.

public void ConfigureServices(IServiceCollection services) {
    services.AddMvc();

    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders()
        .AddOpenIddict(); // Add the OpenIddict services after registering Identity.
}


public void Configure(IApplicationBuilder app) {
    app.UseIdentity();

    // Add all the external providers you need before registering OpenIddict:
    app.UseGoogleAuthentication();
    app.UseFacebookAuthentication();

    app.UseOpenIddict();
}
Community
  • 1
  • 1
Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
  • Thanks @Pinpoint, I'll take a good look at this today. Does it take care of account management like password reset etc.? – joshcomley Dec 11 '15 at 12:35
  • Account management is handled by the account controller that comes with the default MVC template. – Kévin Chalet Dec 11 '15 at 12:44
  • Ahh I see, I've just got this up and running on my machine - it's a wonderful project! Once again, congratulations. It does and it doesn't answer my question I think, though. I am looking for a REST based AccountController than can be called directly via any language to programmatically manage accounts from any client natively. – joshcomley Dec 11 '15 at 13:09
  • I could build this REST controller on top of what you have created here, though, I think. I might give this a go, today. – joshcomley Dec 11 '15 at 13:10
  • Adding a management API to create/update/remove users/applications/authorizations is definitely on our todo-list (we'll have a separate repository for that: https://github.com/openiddict/management), but we'll probably never support adding "social authentication providers" in Web API controllers (i.e in non-interactive controllers) as it proved to be a terribly inappropriate approach (https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/issues/173). – Kévin Chalet Dec 11 '15 at 13:16
  • The problem I am trying to solve is having, for example, a web app and accompanying phone app that support logging in via individual or social accounts, getting their tokens and data from my own REST API and token server. As an expert in this field, what approach would you recommend for this? – joshcomley Dec 11 '15 at 13:31
  • (I'm currently reading through the last link in your last comment!) – joshcomley Dec 11 '15 at 13:33
  • There are basically 2 ways to solve that: the first - and most common/popular - approach is to use a web view that renders the authentication and authorization pages returned by the identity server, that handles the whole process (user registration, local/external login, addition of new social accounts): when the user gives his consent, a token is returned by the OP to your client application, and you can start making API calls with the access token corresponding to the logged in user. – Kévin Chalet Dec 11 '15 at 13:40
  • My current idea is that each front end client uses the REST API to create manual accounts, and implements its own support for social logins. This means that if a phone app would like to use the native Facebook app to support logging in via Facebook, it can, but it would then need to pass the social login token it receives and an email address to the REST API when registering a new account socially. – joshcomley Dec 11 '15 at 13:40
  • The other one is a bit more complex: the client applications are directly registered with the external providers you want to support (e.g FB) and retrieve a token from the social providers they can exchange with your own identity server for a token supported by your API. It's harder to implement and until now, it was not really standard (there's now an official OAuth2 assertion grant spec, but it requires standard tokens like JWT or SAML2 tokens, that are not used by FB). The first approach is definitely the easiest one. – Kévin Chalet Dec 11 '15 at 13:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97647/discussion-between-joshcomley-and-pinpoint). – joshcomley Dec 11 '15 at 13:47
  • Alternatively you might want to give IdentityServer4 a try. It is the official Microsoft recommended solution going forward. The current release runs on RC1 but we will update to RC2 shortly after it is released. https://github.com/IdentityServer/IdentityServer4.Samples – leastprivilege May 02 '16 at 06:56