Open christallire opened 10 months ago
Same here. Since RC1 I can't migrate without this issue.
@halter73 Would you be able to look into this?
Another thing I noticed Is that an authorization check (the route with [Authorize] Attribute) is done before the component lifecycle or Routing. For an example. I used to put OnInitialized and handle some logic in what we now call Routes.razor. When I refresh the page, no routing or component lifecycle logic runs. Is this where we have the bug?
.NET 7.0 No auth - Route OnInitialized = YES Req Auth- Route OnInitialized = YES
.NET 8.0 No auth - Route Oninitialized = YES Req Auth - Route OnInitialized = NO
Upon investigating all other interactivity - the same thing happens when refresh. It looks like there's something with pipeline.
it seems the new 8.0 routing adds pages with [Authorization] to route, so that they have authorization metadata and can be checked with AuthorizationMiddleware if we prerender or first render (when we have HttpContext)
The request runs through pipelines, Invoking Authentication middleware first, and if this fails (no login, so always) - doing redirection defined in middleware. But this is different, especially when we navigate with SPA and there's no Authentication middleware (obviously), and AuthenticationStateProvider is invoked instead of the middleware.
I think someone really messed this up.
edit: When I add JwtBearer authentication to the application they just throw 401 so authorization middleware it is.
@MackinnonBuck can we urgently have a look into this? this seems serious because Authorization in blazor is basically broken.
I'm experiencing the same issue as @christallire. This was working as expected in NET 7. In my case I'm using a Cookie for auth but I don't utilize the Cookie's options.LoginPath
configuration. I prefer to use the <NotAuthorized>
template directive.
@halter73 @MackinnonBuck @mkArtakMSFT
I did some digging, it seems like the user Claims are no longer returned from /manage/info
from the .MapIdentityApi<User>()
.
This change broke my app, worked in RC2 not in RTM. Is this intentional? Possibly related.
IdentityApiEndpointRouteBuilderExtensions.cs
, line 455:
private static async Task<InfoResponse> CreateInfoResponseAsync<TUser>(TUser user, UserManager<TUser> userManager)
where TUser : class
{
return new()
{
Email = await userManager.GetEmailAsync(user) ?? throw new NotSupportedException("Users must have an email."),
IsEmailConfirmed = await userManager.IsEmailConfirmedAsync(user),
};
}
@christallire How do you implement the AuthenticationStateProvider
and do you pass your claims to it? If so, could you check whether your claims are empty or not?
@christallire How do you implement the
AuthenticationStateProvider
and do you pass your claims to it? If so, could you check whether your claims are empty or not?
(edit: oh shoot sorry I thought you're asking me about my "original" implementation)
I haven't changed anything from the template project except RedirectToLogin
part.
Well, I found a workaround by: define following class and register it where server initializes
public class BlazorAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler
{
public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
{
return next(context);
}
}
and handler:
services.AddSingleton<IAuthorizationMiddlewareResultHandler, BlazorAuthorizationMiddlewareResultHandler>();
This class will prevent redirection from the new .net 8 authorization middleware response. The problem still exists, but we can at least we can use .NET 8 new feature the way we used to in Blazor and .NET 7.
You may need to separate endpoint routing other than blazor routes since it basically renders serverside authorization (via .AddAuthentication(...).AddJwtBearer(...)
) ineffective.
hope this helps, enjoy .net 8. while the team fixes the problem.
After investigation, I can understand it's by design now. But this is still a very weird behavior of navigation.
If the interactive is not ready, the app is matching Static Stuff Routes
, the request route is managed by the pipeline. It will be redirected by CookieAuthentication*
stuff. Only after the app is ready to be interactive, the interactive Routes
component takes over the routing. If you refresh the browser manually, there is no ready interactive component.
This is just one of the problems that may arise. A worse scenario is the pages may flicker caused by this. Because the Static Response
during Prerender may significantly differ from the Interactive Content
. Check #51203 to see the behavior.
A deeper investigation is under #52176
I'm afraid I have to disagree that this problem can be solved with documentation.
Well, I found a workaround by: define following class and register it where server initializes
public class BlazorAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler { public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { return next(context); } }
and handler:
services.AddSingleton<IAuthorizationMiddlewareResultHandler, BlazorAuthorizationMiddlewareResultHandler>();
This class will prevent redirection from the new .net 8 authorization middleware response. The problem still exists, but we can at least we can use .NET 8 new feature the way we used to in Blazor and .NET 7.
You may need to separate endpoint routing other than blazor routes since it basically renders serverside authorization (via
.AddAuthentication(...).AddJwtBearer(...)
) ineffective.hope this helps, enjoy .net 8. while the team fixes the problem.
The Blazor Server template with .Net 8 and Identity worked fine out of the box for me. But with the Jwt-Bearer as authentication the symptoms where exactly the same. The 401 http response code was thrown instead, before the AuthorizeRouteView component kicked in and isn't able to redirect to login this way.
The workaround of above works like a charm. I unfortunately don't have time to dig in further why this works.
This is my program minimal api authentication code:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
if (context.Request.Cookies.TryGetValue("token", out var token))
{
context.Token = token;
}
return Task.CompletedTask;
}
};
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuerSigningKey = false,
ValidateIssuer = false,
SignatureValidator = (token, parameters) => new Microsoft.IdentityModel.JsonWebTokens.JsonWebToken(token)
};
});
Well, I found a workaround by: define following class and register it where server initializes
public class BlazorAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler { public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { return next(context); } }
and handler:
services.AddSingleton<IAuthorizationMiddlewareResultHandler, BlazorAuthorizationMiddlewareResultHandler>();
This class will prevent redirection from the new .net 8 authorization middleware response. The problem still exists, but we can at least we can use .NET 8 new feature the way we used to in Blazor and .NET 7. You may need to separate endpoint routing other than blazor routes since it basically renders serverside authorization (via
.AddAuthentication(...).AddJwtBearer(...)
) ineffective. hope this helps, enjoy .net 8. while the team fixes the problem.The Blazor Server template with .Net 8 and Identity worked fine out of the box for me. But with the Jwt-Bearer as authentication the symptoms where exactly the same. The 401 http response code was thrown instead, before the AuthorizeRouteView component kicked in and isn't able to redirect to login this way.
The workaround of above works like a charm. I unfortunately don't have time to dig in further why this works.
This is my program minimal api authentication code:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.Events = new JwtBearerEvents { OnMessageReceived = context => { if (context.Request.Cookies.TryGetValue("token", out var token)) { context.Token = token; } return Task.CompletedTask; } }; options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false, ValidateIssuerSigningKey = false, ValidateIssuer = false, SignatureValidator = (token, parameters) => new Microsoft.IdentityModel.JsonWebTokens.JsonWebToken(token) }; });
You don't need that on the client side; the same happened to me. I removed it, and it worked perfectly. It's only used in the API code.
We have a similar issue with Blazor Webassembly (hosted) and I tried applying the workaround in the Host API, but it didn't work. Anyone have any idea how to solve it in WASM?
Same problem as @dustrat reported
Running into the same issue with Blazor WASM as @dustrat and @pablofrommars
Well, I found a workaround by: define following class and register it where server initializes
public class BlazorAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler { public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { return next(context); } }
and handler:
services.AddSingleton<IAuthorizationMiddlewareResultHandler, BlazorAuthorizationMiddlewareResultHandler>();
This class will prevent redirection from the new .net 8 authorization middleware response. The problem still exists, but we can at least we can use .NET 8 new feature the way we used to in Blazor and .NET 7.
You may need to separate endpoint routing other than blazor routes since it basically renders server-side authorization (via
.AddAuthentication(...).AddJwtBearer(...)
) ineffective.hope this helps, enjoy .net 8. while the team fixes the problem.
Encountering the same problem and ended up using your recommended workaround, so thanks a lot for the hint. This unfortunately has some implications. The project I am working on using OIDC for logging in users, so the authorization result Challenged
still needs to intercept to call for the OAuth 2.0 redirect to the identity provider. I have solved this by making this adjustment:
public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
{
if (authorizeResult.Challenged)
await _defaultHandler.HandleAsync(next, context, policy, authorizeResult);
else
await next(context);
}
However, my biggest concern is the implication which you already mentioned. This more or less disables the ASP.NET authorization layer, so if you have an API you must move that one to another project. I would like to re-use the cookie session but this is not as straight forward anymore. I will look into using a shared state for the cookie data protection and might be able to re-use the cookie when Blazor project and API are running under the same domain. Another way would be to either re-use the id_token
or access_token
for the API. Probably the id_token
because this is the token meant to be for the application and not the underlying APIs (so a different API layer). So to say the JWT bearer.
Nevertheless—even assuming finding a good solution—this definitely does not seem optimal and might be difficult for not so experienced programmers. It would be nice if the ASP.NET middleware somehow knows when a request is meant to be routed to Blazor. I have not looked too much into it yet, but as HttpContext
, AuthorizationPolicy
and PolicyAuthorizationResult
are available one could probably build something here.
The main thing is, it does not really feel "round", it would be nice if Blazor projects with authentication and authorization would be carved into one stone. I do not have a good solution here, but hope that I could lay out the problem a bit more in detail.
Edit: On another note, I also noticed another issue if you use Blazor SSR and WebAssembly only for interactivity. In this case, no AuthenticationStateProvider
is registered, which means that you will get a runtime exception when using builder.Services.AddCascadingAuthenticationState();
. It feels that a default implementation mapping the authentication state, the same way at the Blazor server project uses, would suffice as a good starting point. It feels that there are so many "manual" tweaks one has to do to get a standard setup "Blazor with OIDC" to work properly.
Thanks for reading!
Running into the same issue with Blazor WASM as @dustrat and @pablofrommars
Are you using the new MapRazorComponents<App>()
with AddInteractiveWebAssemblyRenderMode()
, or are you trying to keep a hosted Blazor WebAssembly app working with <component type="typeof(App)" render-mode="WebAssembly">
in a _Host.cshtml
? Can someone please provide a copy of what they've tried so far to get Blazor WASM working?
Latest visual studio, starting a new blazor project, no interactivity (just SSR), the <RedirectToLogin/>
never gets hit when clicking on the "Auth Required" link. When navigating to Account/Manage/Index without being authenticated it redirects me to InvalidUser which is a redirection hapenning in the IdentityUserAccessor. The _imports file has an [Authorize] attribute. Shouldn't the authorize attribute work first before the IdentityUserAccessor used inside the component? Bug or by design?
I'm currently working on a .NET 8 Blazor PWA implenting Auth0 B2C and am having the same issue. In the <AuthorizeRouteView>
, the <Authorizing>
component is hit. However, the <NotAuthorized>
component is just straight up ignored. What's worse, it's not until I have an exception thrown by my API and bubbled up to the browser due to a lack of access token that a call to authentication/login
actually does what it's supposed to. Adding `[Authorize]' to the _Imports file does absolutely nothing.
I am also following best practice and not using Cookie Authentication.
I'm not sure if I'm missing something or what the issue is. Some guidance would be appreciated.
EDIT:
So I finally figured out that I have to explicitly put the [Authorize]
attribute on top of each page I want to secure. So placing an attribute in _Imports has no affect, using an AuthorizeView in my main layout just created an infinite loop of authentication requests.
Perhaps I'm not securing my entire client app correctly? I would think I should just be able to specify that my app can only be used by authorized users.
It's been 4 months, the problem is still there. The docs are wrong saying that the RedirectToLogin
component is doing the redirection (https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-8.0&preserve-view=true#customize-unauthorized-content-with-the-router-component). This is not true, the component is never fired. It can be reproduced by:
RedirectToLogin.razor
inside OnInitialized
<NotAuthorized>
section inside Routes.razor
was not triggered) but user is redirected to login page by some other meansHere is the Routes.razor
for reference from this project:
@using IndetityAuth.Components.Account.Shared
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
Some comments here indicate this is by design, but it's really a puzzle to understand what is going on with all the auth and redirection magic. It is really disappointing such a basic security mechanism seems to be broken since Nov 2023. I am working on a custom setup with external auth provider and making blazor part work is a nightmare. I think I will resort to AuthorizeView
in the MainLayout and other pages probably for now.
I have a smiliar problem where the basic authentication and redirects are working but as soon as I implement any further authorization rules on a page (role or policy based) it just infinitly loops between the redirectToLogin component and tries to authenticated the already logged-in user.
realted issue: https://github.com/dotnet/aspnetcore/issues/19855
I abandoned the AuthorizeRouteView all together since I could only get it to properly trigger the NotAuthorized portion after trying to render a page that had the Authorize attribute on it. I decided to do an AuthorizeView in the main layout with the RedirectToLogin component in the NotAuthorized portion. This seems to work as the AuthorizeRouteView should. And I guess technically since at the App.razor level you're working with the routes and not with the pages directly, routes are not what is being secured but the actual page. However, at the AuthorizeRouteView level, I would think there should be an explicit check to see if the current user has Identity.IsAuthenticated be true. If not, then you're not authorized.
None of this seems to function as I think it should. Templating the App.razor in this fashion seems like an oversite if this is not the way Blazor Wasm is intended to work. Sure I currently have a work around for the issue, but it feels wrong to handle the state of authentication from a layout.
I am having a related problem (I think): https://github.com/dotnet/aspnetcore/issues/54666
I'm fairly new to Blazor and .net as a whole and it has been a nightmare trying to figure this out. I've read all sorts of docs but it's a maze if you're not at home in this ecosystem.
I scaffolded the app using the template provided, and set up everyting in Azure AD, authentication for the API works fine when just normally navigating the app, but when the user refreshes all authorization for the api is lost.
Would you like to ask if the current problem has been solved? Thank you!
I have a hosted Blazor WASM app in Asp.Net Core. I have prerendering enabled. My problem was, that builder.Services.AddCascadingAuthenticationState(); is not the same as CascadingAuthenticationState Componente in the Routes.razor despite being described as such. The differenz is while prerendering, the GetAuthenticationStateAsync() method is not called when adding the CascadingAuthenticationState via the ServiceCollection.
Since I have some specially authentication (anonymous user are being logged in with cookies) this was an essential part of my solution.
If someone still struggles with this problem I found another workaround.
services.ConfigureApplicationCookie(opts => { opts.LoginPath = new PathString("/authorize/login"); });
With this workaround when accessing page with [Authorize] attribute it redirects to "/autorize/login" instead of "Account/Login"
Still it would be better if this was fixed on blazor framework level and AuthorizeRouteView worked like it should do
I also just wasted a couple hours on debugging my requests until i found this. I just wanted to do some experimentations with blazor, but this is a real bummer.
it was working from me below that but #19855 is good idea.
..AddCookie(IdentityConstants.ApplicationScheme, opt => opt.LoginPath = "routeUrl")
@flennic I'm also doing OIDC with IdentityServer and I don't seem to need anything more than
public class BlazorAuthorizationMiddlewareResultHandler() : IAuthorizationMiddlewareResultHandler
{
public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
{
await next(context);
}
}
In which case did you need that? User not logged in trying to access a page that requires authorization? How do you have the redirect to login provider implemented?
Also, is there any plan on making Blazor Server easier to integrate with OIDC? I'm doing some hacky stuff in order to refresh the access token and then get it updated in the cookie.
@Usergitbit When combining an API and Blazor in the same project. I now do not remember the exact setup, but the API layer middleware comes before the request gets to Blazor. So e.g. "Unauthorized" should not be blocked by the API, but should be forwarded to Blazor to show a "Hey, you do not have permission to see this page" message. But "Challanged" should respond with the correct OAuth 2.0 / OIDC flow and not forward the request to Blazor.
So the redirect to the identity provider is the default OIDC ASP.NET implementation, it is not handled by Blazor.
And regarding you last point, I agree. The integration for projects where API and Blazor are mixed should be improved. Also I do not understand why refresh token generation is not enabled (or at least implemented) by default as there actually exist Microsoft examples which can be copy and pasted, maybe with minor adjustments which cloud be put into an Action<RefreshOptions>
extension method.
There are even more quirks, e.g. only OAuth 2.0 (for example for an API) where only the JWKS endpoint is used, is also not supported by default. A friendly user provides his own library for fixing that, I think it should be part of the stack the same as OIDC. But there are probably more reasons for it why decisions are made as they are, I only see it from my perspective.
Well, I found a workaround by: define following class and register it where server initializes
public class BlazorAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler { public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { return next(context); } }
and handler:
services.AddSingleton<IAuthorizationMiddlewareResultHandler, BlazorAuthorizationMiddlewareResultHandler>();
This class will prevent redirection from the new .net 8 authorization middleware response. The problem still exists, but we can at least we can use .NET 8 new feature the way we used to in Blazor and .NET 7. You may need to separate endpoint routing other than blazor routes since it basically renders server-side authorization (via
.AddAuthentication(...).AddJwtBearer(...)
) ineffective. hope this helps, enjoy .net 8. while the team fixes the problem.Encountering the same problem and ended up using your recommended workaround, so thanks a lot for the hint. This unfortunately has some implications. The project I am working on using OIDC for logging in users, so the authorization result
Challenged
still needs to intercept to call for the OAuth 2.0 redirect to the identity provider. I have solved this by making this adjustment:public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { if (authorizeResult.Challenged) await _defaultHandler.HandleAsync(next, context, policy, authorizeResult); else await next(context); }
However, my biggest concern is the implication which you already mentioned. This more or less disables the ASP.NET authorization layer, so if you have an API you must move that one to another project. I would like to re-use the cookie session but this is not as straight forward anymore. I will look into using a shared state for the cookie data protection and might be able to re-use the cookie when Blazor project and API are running under the same domain. Another way would be to either re-use the
id_token
oraccess_token
for the API. Probably theid_token
because this is the token meant to be for the application and not the underlying APIs (so a different API layer). So to say the JWT bearer.Nevertheless—even assuming finding a good solution—this definitely does not seem optimal and might be difficult for not so experienced programmers. It would be nice if the ASP.NET middleware somehow knows when a request is meant to be routed to Blazor. I have not looked too much into it yet, but as
HttpContext
,AuthorizationPolicy
andPolicyAuthorizationResult
are available one could probably build something here.The main thing is, it does not really feel "round", it would be nice if Blazor projects with authentication and authorization would be carved into one stone. I do not have a good solution here, but hope that I could lay out the problem a bit more in detail.
Edit: On another note, I also noticed another issue if you use Blazor SSR and WebAssembly only for interactivity. In this case, no
AuthenticationStateProvider
is registered, which means that you will get a runtime exception when usingbuilder.Services.AddCascadingAuthenticationState();
. It feels that a default implementation mapping the authentication state, the same way at the Blazor server project uses, would suffice as a good starting point. It feels that there are so many "manual" tweaks one has to do to get a standard setup "Blazor with OIDC" to work properly.Thanks for reading!
Hi, can you show me your _defaultHandler declaration, please.
@Joaomfcarmo It is a field in the IAuthorizationMiddlewareResultHandler
declared like this:
private readonly AuthorizationMiddlewareResultHandler _defaultHander = new();
Is there official documentation on this yet? I am still using the IAuthorizationMiddlewareResultHandler
workaround on my Blazor Webapp to get the NotAuthorized component to trigger and redirect to a landing page.
The template code is very misleading. Looking at Routes.razor
makes it look like the <RedirectToLogin />
component is where the "magic" happens - which is the way it used to be. As mentioned, that component isn't involved anymore (so why is it in the Routes template??). You can open up the RedirectToLogin.razor file and change the NavigateTo(...)
path but it will still take you to Account/Login?…
. You can put a breakpoint in that component, and it never gets hit.
The solution from @Liandrel about services.ConfigureApplicationCookie(…)
is what finally helped me out - after wasting way too many hours.
The template code is very misleading. Looking at
Routes.razor
makes it look like the<RedirectToLogin />
component is where the "magic" happens - which is the way it used to be. As mentioned, that component isn't involved anymore (so why is it in the Routes template??). You can open up the RedirectToLogin.razor file and change theNavigateTo(...)
path but it will still take you toAccount/Login?…
. You can put a breakpoint in that component, and it never gets hit.The solution from @Liandrel about
services.ConfigureApplicationCookie(…)
is what finally helped me out - after wasting way too many hours.
So I know what the "problem" semes to be: Prerender
NavigateTo(...)
to counter page (or anything else)Something to look out for, if you have prerender enabled:
I does not use RedirectToLogin.razor
when you prerender a page with @attribute [Authorize]
.
This is because:
app.MapRazorComponents<App>()
.[your render modes]
.AddAdditionalAssemblies(typeof(test.Client._Imports).Assembly);
redirects you to the login page, befor App renders Routes.
Simple Fix:
app.MapRazorComponents<App>()
.[your render modes]
.AddAdditionalAssemblies(typeof(test.Client._Imports).Assembly)
.AllowAnonymous();
To be more specific: Asp.Net Core Redirects you while prerender, not Blazor. If you call .AllowAnonymous() App.razor will prerender anonymous and Routes will execute RedirectToLogin or anything else in
<NotAuthorized>
...
</NotAuthorized>
Use this: if you want to change the behavior of Asp.Net core redirecting ur API calls:
.AddIdentityCookies(o =>
{
o.ApplicationCookie?.Configure(
co =>
{
co.Events.OnRedirectToLogin = e =>
{
e.Response.StatusCode = 401;
return Task.CompletedTask;
};
co.Events.OnRedirectToAccessDenied = e =>
{
e.Response.StatusCode = 401;
return Task.CompletedTask;
};
...
});
});
This way, API Endpoints wont send back a redirect result when called from Blazor WASM.
That solution works like a charm. I didn't think about it initially, but it makes perfect sense that it was redirecting to the default login path because of the pre-render on the server. And by allowing all paths to be anonymous, it reaches App.razor and displays the NotAuthorized content.
I had the same issue as described in this post
https://github.com/dotnet/aspnetcore/issues/52317
But instead of doing this overwrite
public class BlazorAuthorizationMiddlewareResultHandler : IAuthorizationMiddlewareResultHandler { public Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { return next(context); } }
I went with making splash screen on routes rather
This way the refresh can happen and after render my javascript interop that reads session for token on auth will work. Wanted to post on initial post but it was close. Hope someone finds this as an helpfull way to workaround the issue and is a better work around without messing with the rest of the auth
I have the same problem. I tried creating custom auth library with Cookie authentication scheme, but it seems whatever is in the Router is not rendered at all.
In all my components where AuthorizeView is used, even though all custom cookies are deleted and the user is logged out via
await _httpContextAccessor.HttpContext.SignOutAsync(LingoDub.Blazor.Auth.Model.Constants.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
The components always render Authorized content...
It would be great if Microsoft provided example implementation of different custom sign in options (openid, jwt bearer, cookie, etc) on both WebAssembly and Server hosting models.
I have the same problem. I tried creating custom auth library with Cookie authentication scheme, but it seems whatever is in the Router is not rendered at all.
In all my components where AuthorizeView is used, even though all custom cookies are deleted and the user is logged out via
await _httpContextAccessor.HttpContext.SignOutAsync(LingoDub.Blazor.Auth.Model.Constants.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
The components always render Authorized content...It would be great if Microsoft provided example implementation of different custom sign in options (openid, jwt bearer, cookie, etc) on both WebAssembly and Server hosting models.
If you use the browser storage then the components need to complete the rendering to be able to access the storage. That is the issue, so adding the loading as I given in the image will sort that out. When you logout are you calling the NotifyAuthenticationStateChanged so that blazor can rerender? For me calling that logs out and no more authorized views show. Only issue is using the browser storage to read and write the auth tokens or cookies, this can be worked around with the loading stuff I shared
@Mecerburn Thank you for sharing a possible solution. I think wrapping Router in an if statement, whose condition is changed only after rendering the page, disables prerendering completely for the whole webapp, and therefore might not be a suitable solution for everyone. Afterall, I want to have prerendering enabled for some pages - it is an awesome feature to have.
I discovered that my issue would be resolved with the workaround proposed above, if I didn't have additional problems in my auth library. I just want to mention the solution, in case someone else wants to implement auth library of their own. There is a very unclear behaviour of ClaimsIdentity constructor, depending on which parameters you pass in, you will get IsAuthenticated property set to always true or always false. I hope that ASP.NET Core team cleans up this confusion. For reference, this blog helped me tackle my problem: https://www.benday.com/2021/08/13/3-common-problems-with-claimsidentity-and-claimsprincipal-in-asp-net-core/
Is there an existing issue for this?
Describe the bug
I've created Blazor WebApp via VS 2022 template with individual identity. No matter what I do,
<AuthorizeRouteView>
and<NotAuthorized>
are not working and redirect any request to /Account/Login. putting<p>not working</p>
doesn't help.Expected Behavior
Prints "not authorized" when you click "Auth Required" in the template app
Steps To Reproduce
1) Create Blazor Web App with Server Interactive render mode, and with Individual Account Authentication type. 2) Replace from "
<RedirectToLogin />
" to "<p>not authorized</p>
" in Routes.razor (to see if your redirection is from RedirectToLogin component) 3) Click "Auth Required" in template app.Exceptions (if any)
No response
.NET Version
8.0.100
Anything else?
This is a blocker since I was migrating .NET 7.0 app to .NET 8.0, but It behaves very differently.