aspnet / Identity

[Archived] ASP.NET Core Identity is the membership system for building ASP.NET Core web applications, including membership, login, and user data. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.97k stars 871 forks source link

ASP.NET Core Identity as a service #1187

Closed danroth27 closed 7 years ago

danroth27 commented 7 years ago

Add a layer to ASP.NET Core Identity that exposes identity as a service.

This service should provide an opinionated and turn-key identity solution that enables customers to easily migrate to Azure AD B2C. The service should support flows for Web Apps and Web APIs as supported today by Azure AD B2C. Apps interact with the service using standardized protocols (OpenID Connect, OAuth 2.0, JSON Web Tokens) while abstracting the user from protocol details. Client token acquisition will be supported through the Microsoft Authentication Library (MSAL). The goal is to provide a consistent identity offering for in-app, on premise, and cloud scenarios.

Benefits of exposing ASP.NET Core Identity as a service:

Out of scope:

brockallen commented 7 years ago

When the title here says "service", do you mean an HTTP-based API on ASP.NET Identity, or is this issue just a general feature list for the already developed Azure on-prem STS as mentioned here: https://twitter.com/PinpointTownes/status/857772475400290306 and several times on the ASP.NET Community standup?

If it's an HTTP-based API on ASP.NET Identity, then I think this is a great feature! So many apps need decoupling from the in-memory only programming model of ASP.NET Identity.

If it's the on-prem STS, then in the past I've heard this positioned as "a STS where your client app can just change a URL and use any STS you want", but these two things:

will make it product specific, and thus the client application code is also then tied to the Microsoft STS product(s). If this is publicized as the goal (and also the constraint), then fine. But if it's positioned as compatible with any other OIDC token service, then it will be misleading.

If the client apps (I guess in the templates) use client libraries that were OIDC RP certified (https://openid.net/certification/#RPs), then you'd have a more believable story for compatibility.

So can we get official clarification on some of these questions? I think it would help the community in evaluating their options.

danroth27 commented 7 years ago

This is only about adding limited OpenID Connect support to ASP.NET Core Identity that aligns with Azure AD B2C, not adding a broader HTTP API over all of ASP.NET Core Identity. Client apps use the standard OpenID Connect and OAuth 2.0 flows for interacting with ASP.NET Core Identity.

brockallen commented 7 years ago

So in short, this "service" is a package that implements OIDC and uses ASP.NET Identity internally to manage the identities, and this OIDC server will behave exactly as Azure B2C?

Is that a fair one-liner summary?

danroth27 commented 7 years ago

Yup, the goal here is to build an aligned identity story across in-app, on premise and cloud scenarios. We want to make it easy to migrate from ASP.NET Core Identity to using Azure AD B2C as a cloud identity service. That said, Azure AD B2C itself produces OIDC compliant messages and we will too, so you can just as easily decide to use any OIDC provider you want (like IdentityServer4, or OpenIdDict).

brockallen commented 7 years ago

That said, Azure AD B2C itself produces OIDC compliant messages and we will too, so you can just as easily decide to use any OIDC provider you want (like IdentityServer4, or OpenIdDict).

While technically correct (and this also includes any other OIDC implementation), each has their own programming model, assumptions, and features. So just because they all do OIDC, it doesn't mean they all do the same thing or provide the same features for you or your security architecture.

Yup, the goal here is to build an aligned identity story across in-app, on premise and cloud scenarios. We want to make it easy to migrate from ASP.NET Core Identity to using Azure AD B2C as a cloud identity service.

So yes, thanks -- I think this clarification is helpful so people can make an informed decision.

kevinchalet commented 7 years ago

Personally, the main concern I have is that the project names you've chosen are way too generic for what appears to be basically a limited "B2C emulator" (credits go to @leastprivilege for the name!) or an "on-premise B2C server". Why not adding the Azure(AD) moniker in the packages name if that's really what it is?

image

Another (cool) option to consider would be to decouple the OIDC handling part from the abstractions/core components (like the token primitives or the applications/tokens stores), that wouldn't be tied to any OIDC implementation and could be reused and plugged into existing stacks like IdSrv or ASOS.

danroth27 commented 7 years ago

Yeah, we've considered putting B2C in the name to make this clearer, but then folks might think you're actually using B2C, when you're not using B2C at all.

We've definitely open to refactoring things so that they are more generally usable. Can you share more details on what factoring you'd like to see?

brockallen commented 7 years ago

Then call it B2C on-prem, or non-cloud B2C, or non-cloud Azure on-prem B2C or some such. If you give it a generic name, we'd not want people getting confused about what they were really getting. As we know, confusion on this platform is already at an all time high.

danroth27 commented 7 years ago

We're open to this. We just need to come up with a name that signals alignment with B2C, but not usage of B2C. Will discuss more after BUILD is over.

leastprivilege commented 7 years ago

B2C Emulator - isn't that what it is?

leastprivilege commented 7 years ago

Refactoring doesnt make sense to me. We certainly wouldn't use it - and you are not building a framework.

In spirit this is a closed source product. I mean - it needs to mirror the exact feature set of a closed source product. So why even open sourcing it?

danroth27 commented 7 years ago

In spirit this is a closed source product. I mean - it needs to mirror the exact feature set of a closed source product. So why even open sourcing it?

There is still value in making the code open source. By making the code open source you can read the code, debug it, build it yourself, incorporate it in your own projects, contribute bug fixes, fill in feature gaps, etc. Not all open source projects will have or need to have an open ended community driven scope. Some projects may have a fixed scope, even a scope tied to a particular business strategy or commercial product, and that should be ok.

Bartmax commented 7 years ago

The actual app code is much simpler and decoupled from its identity concerns

when you say much simpler you meant this?

image

danroth27 commented 7 years ago

That's the identity code, which certainly isn't simple, but I was referring to the actual app code. The app code for most of our templates consists of a single HomeController with Index, About and Contact views. If you enable authentication today then a good chunk of the identity code gets intermingled with your app dwarfing the actual app logic. By separating out the app code into an area and wrapping it in a standard service interface your app and the identity code are decoupled to the point that you can delete the entire identity folder and replace it with an out of process identity provider of your choice.

We plan to simplify the identity code as well. All the code in the Extensions folders we plan to move into framework packages. We want to revisit how email confirmation and two factor auth get setup to make it simpler and purely additive (no more dummy IEmailSender and ISmsSender interfaces). We are also looking at ways to package the controllers and views so they don't have to live in the template.

Bartmax commented 7 years ago

@danroth27 thanks for the reply and eager to see the improvements coming. Btw, speaking of "We are also looking at ways to package the controllers and views so they don't have to live in the template." This is something that would be useful for a lot of scenarios! Whatever option you enable or recommend that we developers can use is very welcome. I was waiting for something to do exactly that for a looong looong time already.

danroth27 commented 7 years ago

We might do something targeted for the identity controllers and views (still under discussion), but if you're looking for a more general purpose solution you should check out the sweet modules framework the Orchard folks built on top of ASP.NET Core for Orchard Core: https://channel9.msdn.com/Shows/On-NET/Sbastien-Ros-Modular-ASPNET-apps

kevinchalet commented 7 years ago

the sweet modules framework the Orchard folks built on top of ASP.NET Core for Orchard Core: https://channel9.msdn.com/Shows/On-NET/Sbastien-Ros-Modular-ASPNET-apps

There's even a built-in OpenID Connect module designed by @jersiovic (that uses OpenIddict under the hood) :trollface:

@danroth27 any idea when the IdentityService repo will go public?

danroth27 commented 7 years ago

All the code for this feature will show up here in the Identity repo. We should have the first PR in place this week.

@javiercn @Eilon

kevinchalet commented 7 years ago

@danroth27 I started playing with the new VS templates and it looks like there's now no way to create a Web API/APP using Identity (aka "individual authentication") without the B2C emulator, which is of course a real PITA.

Is there a plan to fix that?

danroth27 commented 7 years ago

What issues specifically are you running into? We want the app decoupled from its identity concerns by default so that you can easily swap to a different identity provider.

Bartmax commented 7 years ago

We might do something targeted for the identity controllers and views (still under discussion)

please don't and keep the discussion going.

With all the respect to Orchad and what they have implemented which indeed looks awesome. The need to reference two different packages, inject services, have a middleware running to get the concept of modules on an application may be fine but not to package a library with controller(s) and view(s). (As clearly is your scenario and many others).

I strongly believe this is something missing from asp.net framework, and I would love to see First Class Citizen support for this, the fact that you need this also kinda proves my beliefs.

kevinchalet commented 7 years ago

What issues specifically are you running into? We want the app decoupled from its identity concerns by default so that you can easily swap to a different identity provider.

That's also what I want. I don't want to have an embedded B2C emulator when I have actually no plan to use OIDC at all in my Identity-based app. There should be a new option the individual authentication dropdown list offering you to create a "local B2C server".

danroth27 commented 7 years ago

@PinpointTownes We only plan to offer two options for authentication with individual user accounts: in-app or cloud. Having a third option would leave the user with a confusing choice. The use of OIDC for the in-app case has the benefit of allowing the user to easily swap out their identity provider and it is largely transparent to the user.

danroth27 commented 7 years ago

@Bartmax Whatever we do for identity for the controllers and views we will make sure it's something that anyone can do.

brockallen commented 7 years ago

We only plan to offer two options for authentication with individual user accounts: in-app or cloud

In-app means the same as we have today in VS2017, right? Or if this only means you only allow the B2C emulator, then what about those projects that want to build their own STS using ASP.NET Identity?

kevinchalet commented 7 years ago

The use of OIDC for the in-app case has the benefit of allowing the user to easily swap out their identity provider and it is largely transparent to the user.

Meh. It makes absolutely no sense to use a local OIDC server when you know you don't want to use a remote identity provider. What I want is a template similar to the existing Identity template (in VS 2017).

kevinchalet commented 7 years ago

In-app means the same as we have today in VS2017, right?

Nope. When you select individual authentication with in app users store, the B2C emulator is automatically added and you have no way to avoid that.

brockallen commented 7 years ago

Nope. When you select individual authentication with in app users store, the B2C emulator is automatically added and you have no way to avoid that.

Well, then, that's wrong. This is like saying you'd force the MVC template to only run in Azure App Fabric.

danroth27 commented 7 years ago

This is like saying you'd force the MVC template to only run in Azure App Fabric.

Not at all! The only thing the app is tied to is OpenID Connect (and a limited amount of OIDC at that). There is nothing in the template that is tied to B2C or any other Azure specific service. This means that you can easily switch to any OpenID Connect provider (like IdentityServer4 or OpenIdIDict). This setup allows for more choice, not less.

brockallen commented 7 years ago

But where's the ASP.NET Identity starter code? I guess I'm confused, and admittedly I have not installed any of the preview stuff yet.

kevinchalet commented 7 years ago

This means that you can easily switch to any OpenID Connect provider (like IdentityServer4 or OpenIdIDict).

There are many cases where you don't want to use an OIDC provider - local or remote. Embedding the B2C emulator, IdSrv, OpenIddict, ASOS or any other OIDC provider makes no sense when all you want is a simple application with cookies authentication and a local users database.

danroth27 commented 7 years ago

@brockallen All we are doing here is adding a layer to ASP.NET Core Identity that wraps it in OIDC (specifically the flows that Azure AD B2C supports). We then put all the ASP.NET Core Identity code in an area in the template and the app interacts with it through OIDC. If you later decide that you want to use a different identity provider (Azure AD B2C, IdentityServer4, OpenIdDict, etc) you simply delete the entire area folder and configure the app's OIDC options to point at the identity provider of your choice. You can see this in action at the tail end of the Intro to ASP.NET Core 2.0 session at BUILD.

@PinpointTownes To be fair though, using ASP.NET Core Identity was never really simple. The AccountController alone is over 400 lines of code. And that code and the database setup is all still there, virtually unchanged. The addition of the OIDC endpoints was purely additive. We've tried to make the fact that you have a mini OIDC provider in-app as transparent as possible to the user. For many users it should be an implementation detail that we now do a standardized OIDC dance to setup the app cookie, instead of an app specific form post. If you think it's still causing unnecessary friction someplace let us know and we can try to address it.

kevinchalet commented 7 years ago

To be fair though, using ASP.NET Core Identity was never really simple. The AccountController alone is over 400 lines of code. And that code and the database setup is all still there, virtually unchanged.

So your solution to that is to add much more code in the templates - @Bartmax's screenshot is eloquent - making the authentication flow way more complex for people who only need local authentication and don't want to use OIDC? You can't be serious.

If you later decide that you want to use a different identity provider (Azure AD B2C, IdentityServer4, OpenIdDict, etc) you simply delete the entire area folder and configure the app's OIDC options to point at the identity provider of your choice.

I do understand why you're doing that from a business perspective, but forcing people to use your stuff by including it in the base templates without offering a way to opt in/out is unacceptable. What's next? Bloating all the templates with stuff promoting all the Azure services?

To be clear, I have no problem seeing stuff that help you sell more Azure services in the templates, but they must be opt-in. One should be able to create a new app with the minimum stuff needed, instead of having to remove everything manually.

kevinchalet commented 7 years ago

If you later decide that you want to use a different identity provider (Azure AD B2C, IdentityServer4, OpenIdDict, etc) you simply delete the entire area folder and configure the app's OIDC options to point at the identity provider of your choice.

Not really. Getting rid of the B2C emulator artifacts is way more annoying:

mcquiggd commented 7 years ago

Just wanted to reinforce what I believe @PinpointTownes is asking at several points (please correct me if I am wrong):

A1. Scenario: I have already built my own system comprising IdentityServer / Openiddict. I use ASP.Net Identity exposed via my own UI / Web API. Or, I use it directly within my application.

A2. Desire: I want to treat ASP.Net Identity simply as a building block I can wrap with whatever interface, and persist in whatever storage medium I desire (I don't use SQL, I use DocumentDB). Or, not use it at all.

A3. Requirement: It needs to be completely standalone, opt-in only, and not be tied to a service interface that must mirror a closed source product. It must be able to be used in conjunction with data persisted in a jurisdiction of my choosing for compliance purposes. It must be extendable by the community.

Essentially, if ASP.Net Identity is no longer customisable / extendable with a fair probability that future releases are not going to break that, I cannot put my valuable user data into it, and I will create my own / use a truly open source alternative.

I am not trying to sound antagonistic, I just want to outline the typical scenarios for my own company and my clients. If we wanted to migrate a particular customer to B2C, we would achieve that by other means, and not require that all applications use an Identity product that is tied to it in case we want to use it in the future.

cesher commented 7 years ago

At this point in time the appeal of ASP.NET Core is that it is open source, cross-platform and friendly to startups and small application developers. Azure AD B2C on the other hand is not open source, has a tremendously slow release cycle, lacks many features (some of the more important ones are on private preview now, announced at build) and is incredibly expensive.

I'm sorry, but when you compare Azure AD B2C to something like say AWS Cognito, it is pretty clear that one of them is not targeted at the main market of ASP.NET Core. I understand, that this feature will allow anyone to go in and replace B2C with something else, and that's fine, but seeing as to how B2C is not a real viable option for so many at the moment, as stated before it should be an opt in.

Either an opt in, or AD B2C needs to become a compelling service that can justify its pricing with top notch features. But even then, AWS Cognito coming in at at least half the cost of B2C speaks miles about who they are really targeting as their customers.

Bartmax commented 7 years ago

This is not about which OIDC provider is chosen on the templates, pretty sure everyone agree that having B2C as default with a simple "replace point" it's perfect.

The point here is about when you don't want OIDC at all. That's why you have Windows Auth, cookies is just as good as any other option and every option is aimed to solve different scenarios. Current templates lacks the ability to have a cookies provider which is a very most common approach in MVC application.

mcquiggd commented 7 years ago

@Bartmax

This is not about which OIDC provider is chosen on the templates, pretty sure everyone agree that having B2C as default with a simple "replace point" it's perfect.

Keep the current options and add another for Azure B2C for those that want to and can use it. Keep the other templates free from cruft.

But, essentially as long as the actual Identity implementation retains the current level of extensibility and is self-contained without other dependencies / tied to the needs of a closed sourced SAAS interface, then I personally would be happy. I'll just create my own template and use that.

If it isn't, I would hope Brock would fire up MembershipReboot again and let the community rally round and contribute.

ghost commented 7 years ago

+1 for @brockallen continuing Membership Reboot.

We need options, choice of membership. Identity Server and OpenIddict are far more attractive than very expensive Azure B2C. It is just not commercially viable for many people.

danroth27 commented 7 years ago

@PericlesSouza We completely agree! This feature adds OpenID Connect support ASP.NET Core Identity in a way that aligns with Azure AD B2C, but it doesn't use or rely on or use Azure AD B2C at all. By using OpenID Connect you can then easily update your app to use any identity provider you want, including IdentityServer or OpenIdDict. You have complete control over which identity provider you use.

danroth27 commented 7 years ago

@mcquiggd

But, essentially as long as the actual Identity implementation retains the current level of extensibility and is self-contained without other dependencies / tied to the needs of a closed sourced SAAS interface, then I personally would be happy. I'll just create my own template and use that.

Yup, no extensibility was removed by adding this feature and no dependency was introduced on Azure. We are simply adding OIDC support in a way that makes it easily to migrate to our Azure identity services or any OpenID Connect provider that you want. For folks that don't want OIDC support at all you can still use ASP.NET Core Identity to do forms based cookie authentication like you always have been able to do.

kevinchalet commented 7 years ago

For folks that don't want OIDC support at all you can still use ASP.NET Core Identity to do forms based cookie authentication like you always have been able to do.

Not without having to manually remove your "identity service" thingy from the default templates. And it's a total PITA: https://github.com/aspnet/Identity/issues/1187#issuecomment-301136216

danroth27 commented 7 years ago

We want to make the OIDC support as transparent as possible to the point where, for most users, it should be an implementation detail. We can also improve the template so that removing the OIDC stuff is more painless for folks that want that (ex. we're already in the process of removing of all the code in the temporary Extensions folders).

kevinchalet commented 7 years ago

We want to make the OIDC support as transparent as possible.

It really sounds like you're trying to force people to use your OIDC server (otherwise you'd accept offering a default template without any OIDC stuff, just like in VS2015/2017).

danroth27 commented 7 years ago

It really sounds like you're trying to force people to use your OIDC server

We're really not trying to force anyone to do anything. We're trying to decouple apps from ASP.NET Core Identity so that you can choose whatever identity provider you want. We're doing this by wrapping ASP.NET Core Identity in standards complaint service endpoints. By decoupling identity from the app in this way you can then switch to whatever OpenID Connect provider you want whenever you want to. If you don't want the OIDC endpoints at all you can remove them, but we think most customers will want this level of flexibility.

kevinchalet commented 7 years ago

If you don't want the OIDC endpoints at all you can remove them, but we think most customers will want this level of flexibility.

If you're so sure people will want that, why not offering a way to opt out (using a checkbox?) for those who don't want to use OIDC? :smile:

ketrex2 commented 7 years ago

We're really not trying to force anyone to do anything. We're trying to decouple apps from ASP.NET Core Identity so that you can choose whatever identity provider you want.

This seems disingenuous when you describe the issue you're trying to solve as:

This service should provide an opinionated and turn-key identity solution that enables customers to easily migrate to Azure AD B2C.

This doesn't imply flexibility in the Identity service as the goal, but rather, a push/promotion for Azure AD B2C. It definitely flies in the face of the open and composable goals of ASP.NET Core up to this point.

danroth27 commented 7 years ago

@ketrex I can understand how that statement was a bit confusing, so I've updated the issue description to say "easily migrate to Azure AD B2C, or any other OpenID Connect provider". Obviously we would love for you to use our Azure services, but there is nothing that constrains you to do so. Use whatever provider you'd like.

Ponant commented 7 years ago

@danroth27 , what is difficult is that the user needs to decrypt the code to understand it. The template in ASP.NET 2.0 Preview 1 shown above is too abstract, which is the price to pay for the decoupling you mention. While I think the idea is nice, it would help to point to a short tuto that goes through the code (a 20 min video would be best perhaps as this is a preview). Cheers

danroth27 commented 7 years ago

@Ponant Absolutely! You can see the template in action at the end of the Introducing ASP.NET Core 2.0 BUILD talk, but we will work on putting together a more complete walkthrough in the weeks ahead as the template code settles.