-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Describe the bug
When using multiple auth middleware (AzureAD and AzureAdBearer in my case) blazor seems unable to find the logged in user. The user is logged in though, its presented with the azure login ui and visiting a non-blazor page does correctly show the logged in user.
To Reproduce
Steps to reproduce the behavior:
-
Create a new blazor server app in visual studio, with work/School auth.
-
In Startup.cs, replace the
AddAuthenticationandAddControllersWithViewscalls with the followingservices.AddAuthentication(options => { options.DefaultChallengeScheme = AzureADDefaults.AuthenticationScheme; }) .AddAzureAD(options => Configuration.Bind("AzureAd", options)) .AddAzureADBearer(options => Configuration.Bind("AzureAd", options)); services.AddControllersWithViews(options => { var policy = new AuthorizationPolicyBuilder(AzureADDefaults.BearerAuthenticationScheme, AzureADDefaults.AuthenticationScheme) .RequireAuthenticatedUser().Build(); options.Filters.Add(new AuthorizeFilter(policy)); }); -
Run and login
Expected behavior
The blazor app should show the logged in user but blazor in particular seems unable to do so.
looking at the output [with some static file stuff removed]
Request starting HTTP/2 GET https://localhost:5001/
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_Host'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
Route matched with {page = "/_Host", area = "", action = "", controller = ""}. Executing page /_Host
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
Executed page /_Host in 137.3536ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/_Host'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 175.8487ms 200 text/html; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 POST https://localhost:5001/_blazor/negotiate text/plain;charset=UTF-8 0
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_blazor/negotiate'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/_blazor/negotiate'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 17.318ms 200 application/json
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:5001/_blazor?id=NhnoRIeHHoiihpkIjnUnCg
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_blazor'
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
It seems like authorization is successful when serving the _host but then fails later.
Additional context
There are few significant notes about this setup. AzureAD and AzureADBearer is used to use the AzureAD challenge if no auth is provided. In other words, you're ment to be able to open the app in a browser and enter the user login flow, or for a script to make a call to an api using a bearer token as well.
This means the auth filter must specify the Bearer auth first and the AzureAD second, otherwise the Bearer auth overwrites the AzureAD challenge response as user browses to a page. (at least this is my understanding)
i notice though that the log only prints out one auth middleware at the end of the log there, so i wonder if blazor only checks the first auth middleware, the bearer in my case, witch isn't authorized while missing the auth middleware that actually is authorized, i'm just guessing here though
The first request looks like this and calls both auth middlewares
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/_Host'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
Route matched with {page = "/_Host", area = "", action = "", controller = ""}. Executing page /_Host
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes (AzureADBearer, AzureAD).
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
AuthenticationScheme: AzureADJwtBearer was challenged.
info: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[12]
AuthenticationScheme: AzureADOpenID was challenged.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
Executed page /_Host in 474.51980000000003ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/_Host'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 580.8627ms 302
i'm using the latest vs preview and 3.0.100 of the dotnet sdk
This issue also seems a bit similar to #13709 but not quite the same