Identityserver4: Using ASP.NET Core Identity not working for asp.net core 2.1

Created on 8 Jun 2018  路  13Comments  路  Source: IdentityServer/IdentityServer4

Issue / Steps to reproduce the problem

Documented Using ASP.NET Core Identity

Follow the instructions exactly as stated but with an asp.net core 2.1 application.
The problem shows up with both the MVC and Page's versions of WebApp.

I stepped the code and logins are happening, the user is found, etc.
However something is going wrong with cookies where the app doesn't think its logged in.

Let me know if you want me to post a github project for this issue

source code of issue

question

Most helpful comment

To use the shared UI library and not have to scaffold into the project, you can use .AddDefaultUI() as in:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders()
        .AddDefaultUI();

In addition, because the shared UI places these Razor pages in an Identity area, I needed to override the IdSrv URL configuration.

services.AddIdentityServer(options =>
        {
            options.UserInteraction.LoginUrl = "/Identity/Account/Login";
            options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
        })

All 13 comments

I have no issue with ASP.NET Core 2.1.

something is going wrong with cookies where the app doesn't think its logged in.

Could you elaborate?

@SIkebe
source code of issue
The above project has history of the steps I took.

  1. Baseline MVC App.

  2. I am able to create and login a user with zero code change when making a new MVC project with the asp.net core 2.1 templates. These are slightly different than those of the asp.net core 2.0 ones.

  3. When adding in the IdentityServer4 stuff I can no longer login the user. The assumption is that I should be able to in standalone before we start using this app as an IDP.
    history

I was doing an simply QA of the docs to see if it still worked with the latest asp.net core 2.1 templates.

BTW: The following doesn't work as I would expect either.
Quickstarts/6_AspNetIdentity

I ran it as is, and browsed to
http://localhost:5000/account/login
logged in with alice/Pass123$

post login,
there is nothing in

Request.HttpContext.User.Claims

Am I missing something here?

I am experiencing the same problem following the ASP.NET Identity Quickstart. It does look like the quickstarts haven't been updated in a while.

When creating the boilerplate web application here, we now have the option to choose ASP .NET Core 2.1 in addition to 2.0. The quickstart example works great when choosing the 2.0 option, but doesn't work in 2.1.

What happens after entering valid creds is that the user is kicked back to the index page as if they hit the back button. The Register and Login links are in the navbar as opposed to "Hello [email protected]" as expected.

There's no indication of error. Registration works, but after doing so the user is not logged in nor can they log in. I copied the Serilog configuration from another quickstart example. Here's what happens:

2018-06-11 16:23:11.341 -05:00 [INF] You are using the in-memory version of the persisted grant store. This will store consent decisions, authorization codes, refresh and reference tokens in memory only. If you are using any of those features in production, you want to switch to a different store implementation.

2018-06-11 16:23:11.380 -05:00 [DBG] Using idsrv as default scheme for authentication

2018-06-11 16:23:11.383 -05:00 [DBG] Using Identity.External as default scheme for sign-in

2018-06-11 16:23:11.383 -05:00 [DBG] Using Identity.External as default scheme for sign-out

2018-06-11 16:23:11.384 -05:00 [DBG] Using idsrv as default scheme for challenge

2018-06-11 16:23:11.384 -05:00 [DBG] Using idsrv as default scheme for forbid

2018-06-11 16:23:16.675 -05:00 [INF] AuthenticationScheme: Identity.External signed out.

2018-06-11 16:23:35.907 -05:00 [INF] AuthenticationScheme: Identity.Application signed in.

2018-06-11 16:23:35.911 -05:00 [INF] User logged in.

Unlike ASP.NET Core 2.0, version 2.1 has the UI boxed into a Razor Class Library. However, there's still an option to scaffold these old pages onto your web application. I've done so, and it looks like this call completes successfully:

var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);

So the authentication workflow seems to be mostly working right up until the redirect where the logged in state is lost. Simply removing services.AddIdentityServer(...) and app.UseIdentityServer() restore working order.

Please let me know if there's any other information I can provide.

I got this to work by making it look as close to the working Quickstarts/6_AspNetIdentity

#

  1. Change
services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

to

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

source

  1. Bring back the Identity Scaffold
    This was a strange one, because technically it is supposed to work without it. I did not change any code that was brought back. This is all those cshtml files that make up the Identity UI.
    The reason I brought it back was that the Login page didn't even come up so I wanted to debug it. However simply bringing it back made it work.

  2. Added IEmailSender implementation because now logout needs it.

I have a history of start to finish;
history

Thank you @ghstahl, that seems to work for me as well.

First I added

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

and was instantly logged in when I started the application. As you mentioned the login/logout/register buttons don't work until the ASP Identity bits are scaffolded into the application. After doing this things are working great.

I noticed when using the Razor Class Library (RCL) that the broken login button, for example, wanted to route to http://localhost:5000/?area=Identity&page=%2FAccount%2FLogin

However, once scaffolded, it would correctly route to: http://localhost:5000/Identity/Account/Login

I created a separate Core 2.1 MVC application for science and followed the Quickstart example. Everything works except the routing. For example when navigating to an authorized controller endpoint, the client MVC application kicks you back to the login site at the URL http://localhost:5000/account/login?returnUrl=..., which 404's.

However, if you add the identity prefix to it like this: http://localhost:5000/identity/account/login?returnUrl=... then everything works great. Similarly the RequireConsent routing won't work if enabled, for what I suspect is the same reason.

This might be a separate issue though. Happy to log it separately if desired. Cheers!

I think I am at feature parity with my POC asp.net core 2.1 webapp.
source

There was nothing that had to be done with any IdentityServer4 or IdentityServer4.AspNetIdentity stuff, as expected!

We have a documentation issue now with getting folks up to speed on an out of the box AspNet Core 2.1 webapp. The main culprit is that Identity scaffolding, where bringing all the source back solved a lot of problems.

Frankly I find no value in what the AspNet team did to move out UI elements to separate dlls. It makes it difficult to know what is going on, and I personally would never use it. I have been down that road before where we moved all cshtml files into an assembly resource and all it got me was team discontent.

To use the shared UI library and not have to scaffold into the project, you can use .AddDefaultUI() as in:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders()
        .AddDefaultUI();

In addition, because the shared UI places these Razor pages in an Identity area, I needed to override the IdSrv URL configuration.

services.AddIdentityServer(options =>
        {
            options.UserInteraction.LoginUrl = "/Identity/Account/Login";
            options.UserInteraction.LogoutUrl = "/Identity/Account/Logout";
        })

As @DarranShepherd suggested, adding AddDefaultUi lets you avoid scaffolding all of the objects.

Regarding routing, IdentityServer4 is looking for old root or account routes, when now most of the routes are prepended with "/identity". You can't just point the client to "url/Identity" because that breaks idsrv's discovery functionality. The solution seems to be to strip "/identity" from the routes in the server (Credit to UnknownQuestions from this thread):

services.AddMvc() .AddRazorPagesOptions(o => o.Conventions.AddAreaFolderRouteModelConvention("Identity", "/Account/", model => { foreach (var selector in model.Selectors) { var attributeRouteModel = selector.AttributeRouteModel; attributeRouteModel.Order = -1; attributeRouteModel.Template = attributeRouteModel.Template.Remove(0, "Identity".Length); } })) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

As an aside and off-topic re idsrv, I really don't like the changes to Asp.Net Core Identity. They've put so much of it into a black box - controllers and views - that even if you scaffold the UI, you're still left with a big black box in a high-visibility part of your project. I also take issue with the "/identity" routing, which basically announces to the world stuff about your stack that nobody needs to know.

/end rant/

I really don't like the changes to Asp.Net Core Identity

amen

All set on this issue -- can we close?

Thanks all for the info. I wasted a day on this and decided just to go with the 2.0 asp.net identity template. Any chance of documenting the issues with 2.1 and ids4 on this link so others don't suffer :)??

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings