openiddict / openiddict-core

Flexible and versatile OAuth 2.0/OpenID Connect stack for .NET
https://openiddict.com/
Apache License 2.0
4.44k stars 522 forks source link

[Help wanted] Cant integrate JWT with cookie #564

Closed ngohungphuc closed 6 years ago

ngohungphuc commented 6 years ago

So I want to use JWT to protect my API route. Cookie to protect MVC The problem I have is when I navigate to http://localhost:5000/Account/Login then I success login I will be redirect to http://localhost:5000/Account/Login/?ReturnUrl=%2FPortal%2FIndex not http://localhost:5000/Portal/Index

Here is my controller I want to protect using cookie scheme PortalController.cs

Cookie setup from line 136 and the rest is openid setup

My authorize controller

Am I missing something ?

kevinchalet commented 6 years ago

Out of curiosity, why register a separate cookie instance? https://github.com/Awesome-CMS-Core/Awesome-CMS-Core/blob/master/src/AwesomeCMSCore/AwesomeCMSCore/Extension/ServiceCollectionExtensions.cs#L131-L132 already does it for you.

ngohungphuc commented 6 years ago

@PinpointTownes you mean this line ?

   services.AddAuthentication("AwesomeCMSCookie")
                .AddCookie("AwesomeCMSCookie", options =>
                {
                    options.LoginPath = "/Account/Login/";
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
                });

If that you want to ask I want to register cookie scheme AwesomeCMSCookie

kevinchalet commented 6 years ago

Identity already registers an "application cookie" instance: https://github.com/aspnet/Identity/blob/dev/src/Identity/IdentityServiceCollectionExtensions.cs#L74-L81. Not sure why you need an other instance.

ngohungphuc commented 6 years ago

@PinpointTownes the issue still happend when I change to this

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                    {
                        options.LoginPath = new PathString("/account/login");
                    }
                );
kevinchalet commented 6 years ago

For the same reason: you're still creating a custom cookie instead of using Identity's built-in one. Remove that.

ngohungphuc commented 6 years ago

@PinpointTownes Yes I try to remove it for first place and I got this exeption

InvalidOperationException: No IAuthenticationSignInHandler is configured to handle sign in for the scheme: Cookies
kevinchalet commented 6 years ago

Identity uses a different value: IdentityConstants.ApplicationScheme

ngohungphuc commented 6 years ago

@PinpointTownes where should I put that

kevinchalet commented 6 years ago

Did you take a look at our samples?

ngohungphuc commented 6 years ago

@PinpointTownes Here is my update code the issue still happend AuthorizationController

ServiceCollectionExtensions

kevinchalet commented 6 years ago

HEH, why do you return an authentication cookie from the Exchange action? It's a pure abomination from a security perspective, as this action is not protected by antiforgery countermeasures.

ngohungphuc commented 6 years ago

Not sure if I get what you mean you want me to delete this await SignInCookie(user.UserName, user.Email); I dont see any cookie return in exchange action that you mention.Could you point me directly in the file

kevinchalet commented 6 years ago

I dont see any cookie return in exchange action that you mention.

https://github.com/Awesome-CMS-Core/Awesome-CMS-Core/blob/master/src/AwesomeCMSCore/Modules/AwesomeCMSCore.Modules.Admin/Controllers/AuthorizationController.cs#L155-L156

https://github.com/Awesome-CMS-Core/Awesome-CMS-Core/blob/master/src/AwesomeCMSCore/Modules/AwesomeCMSCore.Modules.Admin/Controllers/AuthorizationController.cs#L160-L210

ngohungphuc commented 6 years ago

@PinpointTownes the issue still happend even I remove the cookie code

https://github.com/Awesome-CMS-Core/Awesome-CMS-Core/blob/master/src/AwesomeCMSCore/Modules/AwesomeCMSCore.Modules.Admin/Controllers/AuthorizationController.cs

ngohungphuc commented 6 years ago

@PinpointTownes any ideas

kevinchalet commented 6 years ago

What's the exact error you're seeing? Also, you should post your logs, otherwise it's hard to help you.

ngohungphuc commented 6 years ago

@PinpointTownes like i said before

The problem I have is when I navigate to http://localhost:5000/Account/Login then I success login I will be redirect to http://localhost:5000/Account/Login/?ReturnUrl=%2FPortal%2FIndex not http://localhost:5000/Portal/Index

kevinchalet commented 6 years ago

Your issue has pretty much nothing to do with OpenIddict (it's purely a cookie/Identity issue), but I'll try to take a look when I have some time.

ngohungphuc commented 6 years ago

@PinpointTownes I try with RefreshFlow sample and I the error is still happend.

kevinchalet commented 6 years ago

@ngohungphuc not sure how that's possible since the refresh token flow sample doesn't use cookie authentication and doesn't have an /Account/Login endpoint.

ngohungphuc commented 6 years ago

@PinpointTownes I added view to test it. I think the problem when we validate the user credentail we dont store it in cookie

ASP.Net invidual authentication boilerplate code var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);

Refresh flow code var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, lockoutOnFailure: true);

kevinchalet commented 6 years ago

Maybe my previous messages were not clear enough but the password flow doesn't use cookies. Don't be surprised if you see weird errors when trying to add cookie authentication for something that doesn't leverage cookies.

ngohungphuc commented 6 years ago

So I have to manual add cookie authentication scheme in exchange method ?

kevinchalet commented 6 years ago

I'm going to repeat it one more time: don't use cookies in the Exchange method. It's an API action.

ngohungphuc commented 6 years ago

So is there anyway to achieve my goal

kevinchalet commented 6 years ago

So is there anyway to achieve my goal

You haven't even explained it.

ngohungphuc commented 6 years ago

I want to store a cookie when user login success. And a token return from exchange method use to protect API. Cookie to protect Admin route.

kevinchalet commented 6 years ago

I want to store a cookie when user login success.

You can do that from the regular AccountController, but not in Exchange, which doesn't use cookie authentication: password is a non-interactive OAuth2 flow: you send the username and the password and you get back a token. No cookie is involved.

You can use cookies for your website, and the password flow w/tokens for your APIs. The two worlds are separate.

ngohungphuc commented 6 years ago

Got it thank you