Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BFF After login Redirect within Sub App #60

Closed
Zarrdex opened this issue May 17, 2022 · 13 comments
Closed

BFF After login Redirect within Sub App #60

Zarrdex opened this issue May 17, 2022 · 13 comments

Comments

@Zarrdex
Copy link

Zarrdex commented May 17, 2022

Which version of Duende BFF are you using?
Duende.BFF V: 1.1.3

Which version of .NET are you using?
net6.0

Describe the bug
I have a blazor webassembly app that needs to run in a sub app (virtual directory).

When logging into the site, i am correctly redirected to the authenitcation server (Duende.IdentityServer V 6.0.4) using BFF

After Logging in i get redirected back to the root path (https://localhost:5001) not the sub app path (https://localhost:5001/Test/)

If i try and go to the sub path, it resends me to the login page.

But if I run the blazor webassembly app not as a sub app, everything is working correctly with no issue's at all.

So I am thinking this is a set-up issue, but must be missing something important, any help would be most appreciated

To Reproduce
using https://github.com/DuendeSoftware/BFF/tree/main/samples/Blazor6

Client:
Change the index file base href to

Server
Program.cs add app.UsePathBase("/Test"); just after var app = builder.Build();
launchSettings.json add the "LaunchURl": "Test" as to run the app in the sub app

Duende.IdentityServer
Change the config Uri's to include the sub app
new Client
{
ClientId = "wasm",
ClientName = "wasm",
ClientUri = "https://localhost:5001/**test**",
ClientSecrets =
{
new Secret("secret".Sha256())
},
RequireClientSecret = true,
RequirePkce = true,
AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true,
AllowedGrantTypes = GrantTypes.Code,
BackChannelLogoutUri = "https://localhost:5001/**test**/bff/backchannel",
RedirectUris=
{
"https://localhost:5001/**test**/signin-oidc"
},
PostLogoutRedirectUris =
{
"https://localhost:5001/**test**/signout-callback-oidc"
},
FrontChannelLogoutUri = "https://localhost:5001/**test**/signout-oidc",
AllowOfflineAccess = true,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,

        }

Expected behavior
After logging into to be redirected back to the original site (https://localhost:5001/Test/) + return URL and

Log output/exception with stacktrace
N/A

Additional context
builder.Services.AddBff(options =>
{
options.ManagementBasePath = "/bff";
});

builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
options.DefaultSignOutScheme = "oidc";
})
.AddCookie("cookie", options =>
{
// set session lifetime
options.ExpireTimeSpan = TimeSpan.FromHours(8);
// sliding or absolute
options.SlidingExpiration = false;
options.Cookie.Name = "__Host-blazor";
options.Cookie.SameSite = SameSiteMode.Strict;
options.Events.OnSigningOut = async e =>
{
// automatically revoke refresh token at signout time
await e.HttpContext.RevokeUserRefreshTokenAsync();
};
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5000";

    // confidential client using code flow + PKCE
    options.ClientId = "wasm";
    options.ClientSecret = "secret";
    options.ResponseType = "code";
    options.ResponseMode = "query";

    // request scopes + refresh tokens
    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("offline_access");

    options.MapInboundClaims = false;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.SaveTokens = true;


});
@brockallen
Copy link
Member

I think having UsePathBase is not right, unless you have some reverse proxy actually multiplexing and forwarding requests to several different web servers internally. If you're running in a proper child app in IIS, then you want the ~/Test path to remain in there, right?

@Zarrdex
Copy link
Author

Zarrdex commented May 17, 2022

Hi brockallen,

I have updated the software to the latest but still have the issue.

The app will be hosted in a vitrual directory in IIS (or sub app). This means yes having the UsePathBase ~/Test is correct in this circumstance, otherwise the blazor won't load or find the blazor.webassembly.js as well as the other resources.

Please note this is on a single web server so there is no "reverse proxy actually multiplexing and forwarding requests".

The IIS set-up will be like
Main Site (MVC app that does not interact with the Test App but does with the Authentication Server)

Authentication Server
Test App

@brockallen
Copy link
Member

This means yes having the UsePathBase ~/Test is correct in this circumstance

I'm still confused. What URL do you expect the browser to see? And what's the "real" URL/path the app is on (meaning what URL does your app see before the UsePathBase middleware)?

Also, this:

Change the index file base href to

I don't see anything in your original post, so perhaps that's important?

@Zarrdex
Copy link
Author

Zarrdex commented May 18, 2022

Hi Brockallen

Sorry, the code must have been stripped for the "Change the index base href to"
In the client wwwroot/index file change the base href to /Test/, this will ensure that the blazor assembly runs in the sub app (as well as on the server having app.UsePathBase("/Test"));

App's URL's
Without the app path: https://localhost:5001/
With the app path: https://localhost:5001/Test/

Current route whats happening
Start: Sub app: https://localhost:5001/Test/
Step 1: Redirect to the authentication server and pass through the returnURL
Step 2:-> Goes to authentication server https://localhost:5000/Authentication/
Step 3: Login
Step 4: Redirect back to sub app
-> Expected: https://localhost:5001/Test + ReturnURL
-> Actual: https://localhost:5001 + ReturnURL

@brockallen
Copy link
Member

brockallen commented May 18, 2022

I think something about this app path and base herf is causing issues, and unless I were to debug it I'm not sure I know what the issue is.

I'd suggest building a standalone bare-bones ASP.NET Core web app that does OIDC and cookies like your blazor app and then add the home page and set the base href the same way. Get that to work without blazor and without BFF. Once you have that working, then you'll know the expected paths, callback paths, etc and how they should work with your virtual directory design. Then you will know and understand the differences needed in your blazor/BFF app.

If I have time later this week, I'll try to repro what I think you're doing. But I do know we have people using BFF in a virtual directory and that's working properly. I just don't know about the base href and the UsePathBase mixed in.

@Zarrdex
Copy link
Author

Zarrdex commented May 18, 2022

Hi Brockallen,

Just for your information in regards to the app path and base href which is needed to run the project as a sub app.

Here is a link to microsoft that describe how to set up a sub app project (The project is a Hosted Blazor WebAssembly:)
https://docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/?view=aspnetcore-6.0&tabs=visual-studio#app-base-path

Thanks, if you could try and repro it that would be brilliant.

I will try in an ASP.NET Core web app and come back to you.

@brockallen
Copy link
Member

Hi @Zarrdex -- I tried to repo your setup on IIS. I did find a bug, but before I ever got to try to test the UsePathBase. It's likely it's the issue, but I'm not 100% sure. So I'll get a preview out for you to test -- sound ok?

@Zarrdex
Copy link
Author

Zarrdex commented May 24, 2022

Hi BrockAllen,

Thanks for finding the issue, and i would be happy to test the change

@brockallen
Copy link
Member

I merged the PR, and so there should be a build on our dev NuGet feed as described here. Can you try that, please?

@Zarrdex
Copy link
Author

Zarrdex commented May 25, 2022

Hi BrockAllen,

I installed
Duende.BFF : 1.2.2-alpha.0.1
Duende.BFF.EntityFramework : 1.2.2-alpha.0.1

To test the change, this came back with 2 additional issue's

  1. When setting a returnURL
    This returned to the root just like the original issue.

Start: Sub app: https://localhost:5001/Test/
Step 1: Redirect to the authentication server and pass through the returnURL (example /weatherForcast)
Step 2:-> Goes to authentication server https://localhost:5000/Authentication/
Step 3: Login
Step 4: Redirect back to sub app
-> Expected: https://localhost:5001/**Test** + ReturnURL
-> Actual: https://localhost:5001/ + ReturnURL

thus i think the return URl should be

Root + PathBase + returnURL
E.g.
https://localhost:5001 + /Test + /weatherForcast

  1. When setting No return URL
    This returned to the correct location but it got stuck in a loop whereby the site said it was not authourised which redirected this to the Authentication server which in turn said it was authourised and passed the token back and repeated itself.

Start: Sub app: https://localhost:5001/Test/
Step 1: Redirect to the authentication server
Step 2:-> Goes to authentication server https://localhost:5000/Authentication/
Step 3: Login
Step 4: Redirect back to sub app to the correct basepath (yeah that was fixed)
Step 5: authourisation failed goes to authentication server
Step 6 : authentication server says you already have a valid token returns to Sub abb
Step 7: Repeats Steps 5 and 6 Continously

@brockallen
Copy link
Member

brockallen commented May 31, 2022

Your app should pass the full path reutrnUrl -- our library isn't interpreting it as app relative. This is similar behavior to how the Microsoft code works for the returnUrl for the cookie authentication handler (commonly used on a login page).

Also -- sorry for the delay. There was a lot going on here in the past week.

@brockallen
Copy link
Member

brockallen commented May 31, 2022

Step 4: Redirect back to sub app to the correct basepath (yeah that was fixed)
Step 5: authourisation failed goes to authentication server

This will need more info and debugging on your part. This could be many things. One thing I noticed is that Chrome rejects the local session cookie from our sample cookie given the "__Host" prefix when you run the app in an app base (which means the path gets set on the cookie to something other than just "/"). So if you are using Chrome and use the "__Host" prefix like we do in out sample, try changing the cookie name and remove that prefix, or look into using "__Secure" instead.

https://datatracker.ietf.org/doc/html/draft-west-cookie-prefixes#section-3.2

@Zarrdex
Copy link
Author

Zarrdex commented Jun 1, 2022

Hi Brockallen,

Thank you for this, these recommended changes work brilliantly.

The Return URL definately needs the BasePath to be included (could this be added to the documentation)

Also changing the cookie Name from having the "__Host" fully fixed the issue. Please note that this issue is also in Edge.

@Zarrdex Zarrdex closed this as completed Jun 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants