IdentityServer / IdentityServer4

OpenID Connect and OAuth 2.0 Framework for ASP.NET Core
https://identityserver.io
Apache License 2.0
9.23k stars 4.02k forks source link

Identity Server 4 (2.0) not reading Asp.Net Core Identity cookies #1900

Closed LindaLawton closed 6 years ago

LindaLawton commented 6 years ago

Re-posted from stack overflow i am kind of desperate as i have been trying to get this to work for several days now. I have been though all the tutorials and sample projects i can find none of them use 2.0 with Identity users.

I am trying to use Asp .Net Identity Core with Identity Server 4. I can see in the logs (Ids) that the user is logged in properly.

info: Xena.IdentityServer.Controllers.AccountController[0] User logged in.

My login controller then sends the user over to my Manage controller.

[Route("[controller]/[action]")]
[Authorize]
//[Authorize(AuthenticationSchemes = "Identity.Application")]
public class ManageController : Controller
{

    [HttpGet]
    public async Task<IActionResult> Index(ManageMessageId? message = null)
    {
     ..... 
    }
 }

The User never arrives as the login is then lost for some reason.

info: Microsoft.AspNetCore.Mvc.RedirectToActionResult[2]
      Executing RedirectResult, redirecting to /Manage/Index.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action Xena.IdentityServer.Controllers.AccountController.Login (Xena.IdentityServer) in 3493.6102ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 3515.9158ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request starting HTTP/1.1 GET http://localhost:5000/Manage/Index
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[2]
      Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
      AuthenticationScheme: Bearer was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action Xena.IdentityServer.Controllers.ManageController.Index (Xena.IdentityServer) in 46.2285ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 58.6793ms 401

I think part of the clue is this line Authorization failed for user: (null). I can see that the cookie is in the browser. Its just not being read.

From what I understand Identity server 4 has its own cookies and Asp .Net core Identity has its and they need to be reading the same cookie. I have tried following Using ASP.NET Core Identity but it hasn't helped.

Startup

 //Adds Asp.net identity 
        services.AddDbContext<ApplicationDbContext>(builder =>
            builder.UseSqlServer(Configuration.GetConnectionString("XenaIdentityConnection")));

        // Configuer Asp.net Identity
        services.AddIdentity<ApplicationUser, IdentityRole<long>>(config =>
            {
                config.Password.RequireDigit = true;
                config.Password.RequireLowercase = true;
                config.Password.RequireNonAlphanumeric = false;
                config.Password.RequireUppercase = true;
                config.Password.RequiredLength = 8;
                config.User.RequireUniqueEmail = true;
                config.SignIn.RequireConfirmedEmail = true;
                config.SignIn.RequireConfirmedPhoneNumber = false;
            })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddSignInManager<ApplicationSignInManager>()    // Adds custom SignIn manager.
            .AddDefaultTokenProviders();

   //https://identityserver4.readthedocs.io/en/release/topics/signin.html
        services.AddAuthentication(options =>
            {
                options.DefaultScheme = IdentityConstants.ApplicationScheme;
            })
            .AddGoogle("Google", options =>
            {
                options.AccessType = "offline";
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.ClientId = "xxxxx-jvu30c2n19thoqimd97b4jk1r2poh17p.apps.googleusercontent.com";
                options.ClientSecret = "g29nXgVoFZBIBNS-hJJxPWXW";
            }).AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, "OpenID Connect", options =>
            {
                options.SaveTokens = true;
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.SignOutScheme = IdentityServerConstants.SignoutScheme;
                options.RequireHttpsMetadata = settingsSetup.RequireHttpsMetadata;
                options.Authority = settingsSetup.Authority;
                options.ClientId = "testclient";
                options.Scope.Add("testapi");
                options.ResponseType = OpenIdConnectResponseType.IdTokenToken;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };
            });

Adding the following does fix my issue with manage/index. However it doesn't work because then the open Id connect login wont work because that uses internal controllers within Identity Server for authentication that I cant / don't want to overload. I need to figure out how to get Identity Server 4 to use the cookie set by Aspnet identity or visa versa.

//[Authorize(AuthenticationSchemes = "Identity.Application")]

This solution came from a previous question i asked on Stack I have opened a new one because i am leaning towards this being a setup issue with Identity server rather than an issue with Identity cookies

leastprivilege commented 6 years ago

This should exactly cover your use-case - give it a try and compare

https://github.com/IdentityServer/IdentityServer4.Templates/tree/dev/src/IdentityServer4AspNetIdentity

LindaLawton commented 6 years ago

Ok i checked your link looks a lot like what i already have. I changed mine to this.

services.AddAuthentication() .AddGoogle(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                options.ClientId = "xxxx-9m4dkjb5hscn7cjrn5u0r4tbgkbj1fko.apps.googleusercontent.com";
                options.ClientSecret = "wdfPY6t8H8cecgjlxud__4Gh";
            });

breaks google login. It only works if i set it to this

IdentityConstants.ExternalScheme

Which kind of makes is what makes me thing somethings wrong with how Identty server 4 is loading my cookies its not using IdentityConstants.ExternalScheme its using its own internal ones ( IdentityServerConstants.ExternalCookieAuthenticationScheme) which dont work.

Is there to force it to use IdentityConstants instead of IdentityServerConstants? or maybe tell asp.net identity to use IdentityServerConstants?

Normal user login still has the same error null user. Upgrading to 2.0 has not been easy.

leastprivilege commented 6 years ago

try this change

https://github.com/IdentityServer/IdentityServer4.Templates/pull/23/files

LindaLawton commented 6 years ago

Ok let me try. Question could it be my custom signinManager?

await SignInAsync(user, true, IdentityConstants.ApplicationScheme);

That looks a bit suspicious to me

leastprivilege commented 6 years ago

don't know.

LindaLawton commented 6 years ago

The cookie its creating is called .aspnetcore.identity.application do you remember what the name of the one that ids is expecting?

leastprivilege commented 6 years ago

I updated the template - thats how it is supposed to work with ASP.NET Identity

https://github.com/IdentityServer/IdentityServer4.Templates/tree/2.2.0/src/IdentityServer4AspNetIdentity

LindaLawton commented 6 years ago

I finally figured out the problem this morning. Part of the problem was due to the fact that I have a custom signin manager which uses the IdentityConstant cookies.

services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
                    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
                })

Both DefaultAuthenticateScheme and DefaultChallengeScheme need to be set. Then everything works as it should.

Thanks again for your help.

lock[bot] commented 4 years ago

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.