-
Notifications
You must be signed in to change notification settings - Fork 10k
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
Blazor Authorization - AuthorizeRouteView and RedirectToLogin not working. #52063
Comments
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. .NET 7.0 .NET 8.0 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. 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 |
@halter73 @MackinnonBuck @mkArtakMSFT I did some digging, it seems like the user Claims are no longer returned from This change broke my app, worked in RC2 not in RTM. Is this intentional? Possibly related.
|
@christallire How do you implement the |
(edit: oh shoot sorry I thought you're asking me about my "original" implementation) I haven't changed anything from the template project except |
Well, I found a workaround by:
and handler:
This class will prevent redirection from the new .net 8 authorization middleware response. You may need to separate endpoint routing other than blazor routes since it basically renders serverside authorization (via 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. This is just one of the problems that may arise. A worse scenario is the pages may flicker caused by this. Because the A deeper investigation is under #52176 |
I'm afraid I have to disagree that this problem can be solved with documentation. |
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. |
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.
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.
|
@flennic I'm also doing OIDC with IdentityServer and I don't seem to need anything more than
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 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. |
Hi, can you show me your _defaultHandler declaration, please. |
@Joaomfcarmo It is a field in the private readonly AuthorizationMiddlewareResultHandler _defaultHander = new(); |
Is there official documentation on this yet? I am still using the |
The template code is very misleading. Looking at The solution from @Liandrel about |
So I know what the "problem" semes to be: Prerender
Something to look out for, if you have prerender enabled: This is because:
redirects you to the login page, befor App renders Routes. Simple Fix:
|
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
Use this: if you want to change the behavior of Asp.Net core redirecting ur API calls:
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 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 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: |
@Appli4Ever I believe your cookie approach is the best solution. However, when attempting it myself, it does not work for me. I also tried setting the |
Thanks, this works for me. |
@Woudjee what exactly did not work? Can you share some code? |
I haven’t worked on this problem since I posted. Next week, I will take a look at it again 👍
Op 9 nov. 2024 om 08:48 heeft Simon Müller ***@***.***> het volgende geschreven:
@Woudjee<https://github.com/Woudjee> what exactly did not work? Can you share some code?
—
Reply to this email directly, view it on GitHub<#52063 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AUGP35DKX7WNIZUL5X7CL3TZ7W46DAVCNFSM6AAAAAA7L36HRSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINRWGEYDMNJYHE>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
I recently published a blogpost about this with video showing it: https://www.databinding.net/prerender-mit-blazor-webassembly-wasm-in-asp-net-core-8-teil-3/ It is in german but I am sure your browser can translate it. |
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
<RedirectToLogin />
" to "<p>not authorized</p>
" in Routes.razor (to see if your redirection is from RedirectToLogin component)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.
The text was updated successfully, but these errors were encountered: