aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Blazor Server Side AADB2C AllowAnonymous Not working in latest template

Open MetaHex opened this issue 2 years ago β€’ 32 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

In the latest template for Blazor Server Side with Microsoft Identity platform. program.cs has:

builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy
options.FallbackPolicy = options.DefaultPolicy;
});

So now all pages will direct to login. However, if I want to define a landing page that doesn't require login with

@Attribute [Microsoft.AspNetCore.Authorization.AllowAnonymous], it doesn't work. Page still gets redirected to login.

Maybe this is related to https://github.com/dotnet/aspnetcore/issues/37064 and dotnet/aspnetcore#23157

cc: @guardrex per https://github.com/dotnet/AspNetCore.Docs/issues/24473

Expected Behavior

Pages marked with Attribute AllowAnonymous should not be redirected to login if not logged in

Steps To Reproduce

-Start a project with Blazor Server Side with Microsoft Identity Platform. -Fill in all the required AADB2C configs -Launch the site to see if AADB2C is setup correctly. clean up (logout) -go to index.razor or fetchData.razor and add @Attribute [Microsoft.AspNetCore.Authorization.AllowAnonymous] -Launch site. It still requires AADB2C login on index,razor or fetchData.razor

Exceptions (if any)

No response

.NET Version

6.0.100

Anything else?

No response

MetaHex avatar Jan 05 '22 16:01 MetaHex

Thanks for contacting us.

We're moving this issue to the .NET 7 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost avatar Jan 05 '22 17:01 ghost

Has anyone gotten this to work or have a work around for it?

silentdevnull avatar Jan 08 '22 18:01 silentdevnull

Not I am aware of

Get Outlook for iOShttps://aka.ms/o0ukef


From: silentdevnull @.> Sent: Saturday, January 8, 2022 10:39:32 AM To: dotnet/aspnetcore @.> Cc: MetaHex @.>; Author @.> Subject: Re: [dotnet/aspnetcore] Blazor Server Side AADB2C AllowAnonymous Not working in latest template (Issue #39321)

Has anyone gotten this to work or have a work around for it?

β€” Reply to this email directly, view it on GitHubhttps://github.com/dotnet/aspnetcore/issues/39321#issuecomment-1008099573, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AWOI5HLOZKBD7N3FNHNNZN3UVCAGJANCNFSM5LKK3NZQ. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you authored the thread.Message ID: @.***>

MetaHex avatar Jan 08 '22 18:01 MetaHex

@MetaHex Thanks.

The only workaround I was able to do was to use two projects and a reverse proxy to route the URL to each project. It is a big pain and I'm still trying to work through some of it, but it is slow working and coming together.

Hopefully, the time will get this fixed fast

silentdevnull avatar Jan 12 '22 16:01 silentdevnull

Modifying _Hosts.chtml and opting into auth worked for me. https://stackoverflow.com/questions/60768399/blazor-using-azure-ad-authentication-allowing-anonymous-access

rpskelton2 avatar Jan 20 '22 22:01 rpskelton2

@rpskelton2 I think this was the default case previously. I think MSFT now recommends (at least from their samples) auth to be set by default and allow anonymous on individual pages.

MetaHex avatar Jan 20 '22 23:01 MetaHex

@MetaHex , that's what I tried first but the AllowAnonymous attribute seemed to be ignored. (Server Side Blazor) Whenever I hit my razor page that contained the AllowAnonymous attribute it would redirect me to the Azure login. If you know of a working sample please pass along!

rpskelton2 avatar Jan 21 '22 00:01 rpskelton2

Has anyone been able to figure this out?

tjorvenK avatar May 04 '22 12:05 tjorvenK

Not an actual (or practical) work-around, but we decided to allow anyone to signup in B2C, and instead check for association in our own User table. If user==null then they're "anonymous". This will definitely be changed to AllowAnonymous once working.

larsholm avatar Jun 01 '22 11:06 larsholm

This affects even non-Blazor pages. E.g. endpoints and everything MVC.

hammypants avatar Aug 13 '22 00:08 hammypants

@javiercn @danroth27 I'm evaluating the .NET ecosystem (ASP.NET, Blazor and .NET in general) for our company, and I just got hit with this bug. Unfortunately the workaround (authorize everything + deny specific pages) isn't sufficient for our requirements.

Since I'm not familiar with the codebase, if you point me roughly in the right direction I can dig deeper and prepare a PR with a proposed fix. This could be an interesting opportunity to get my feet wet with .NET. Thanks.

dgiagio avatar Sep 06 '22 20:09 dgiagio

@dgiagio for this particular scenario there are two times that auth plays a role:

  • When the _Host.cshtml Razor page is going to be rendered statically on the server.
  • When the Index.razor page is rendered on the client.

For this to work, you need to support AllowAnonymous on both code paths.

  • In the first case to enable the _Host.cshtml page to render.
  • In the second to allow the Index.razor to render.

The one causing trouble here is likely the _Host.cshtml. In this scenario, I would avoid requiring auth globally as the template does, as that is not what you want.

It is easier to declare the things that require authorization than add authorization for everything and then poke holes.

I do not think there is a bug here, it's just a complex scenario to implement, hence why I recommend the alternative approach.

javiercn avatar Sep 07 '22 11:09 javiercn

Thanks for contacting us.

We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost avatar Oct 05 '22 16:10 ghost

It is easier to declare the things that require authorization than add authorization for everything and then poke holes.

I guess it depends on your application, but it's not easier if 99% of your app needs to be secured, and only a single page needs to allow anonymous.

brianpursley avatar Oct 12 '22 13:10 brianpursley

I added @attribute [AllowAnonymous] to my _Host.cshtml, which stopped the redirect but now the connection is broken between the server and the client due to this JS error: image

Edit: ~~So I removed options.FallbackPolicy = options.DefaultPolicy; and then it all worked OK.~~

EricEzaM avatar Nov 25 '22 16:11 EricEzaM

@EricEzaM If you removed fallback policy, of course it will work.

The ask is for the use case that most site requires login, but we also needs some pages that allows anonymous...

MetaHex avatar Nov 26 '22 09:11 MetaHex

Ah, my apologies, I misunderstood the usage of the Fallback policy.

I agree the problem is frustrating as you do expect the allow anonymous attribute to work with the template as is.

EricEzaM avatar Nov 26 '22 09:11 EricEzaM

I understand this issue is moved to .NET 8 Planning but what do we do with immediate development requirements? i"ve got projects where UI is Blazor Server based and i need to have some components publicly available allowing anonymous access. what do we do?

yandoldonov avatar Feb 21 '23 20:02 yandoldonov

+1, same issue here. Just trying to add one endpoint for a B2C connector, guess I'll go make an azure function instead.

stefan-helios avatar Feb 21 '23 21:02 stefan-helios

I've hit this same issue. After a bit of experimenting I can see that AllowAnonymous works in .cshtml pages but not in .razor pages. Definitely seems to be a bug. I'm surprised this isn't a higher priority, I don't see how I can proceed with Blazor without creating two seperate applications which is too much overhead.

phcd30 avatar Mar 02 '23 11:03 phcd30

@phcd30 I've managed an emergency work-around in a vice-versa authentication/authorization pattern, which sucks but does work. basically, the idea is - you make the root accessible for anonymous and then control authorization on a per-page level.

you set the anonimous flag in the _Host.cshtml file like so:

@page "/"
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Authorization
@attribute [AllowAnonymous]
@namespace YourProjectNameSpace.Blazor.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />    
    <link rel="icon" type="image/png" href="favicon.png"/>
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
    <component type="typeof(App)" render-mode="ServerPrerendered" />

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss">πŸ—™</a>
    </div>

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

but then in each page you have to control authorization by doing this:

@page "/"
@attribute [Authorize]
<PageTitle>Index</PageTitle>

this works but as i said, this approach really sucks because you HAVE to remember to apply authorisation attribute to EACH page but i am unable to wait and have to move forward with development.

yandoldonov avatar Mar 02 '23 11:03 yandoldonov

Thanks @yandoldonov! I'll take this approach as well until something is fixed. I can't believe this has been open for a year so I'm thinking we both must have hit an edge case in our specific use cases. Either that or no-one is using blazor of mixed public and private pages in a normal manner.

I noticed with AWS Cognito template uses cshtml for their public authentication pages, maybe everyone is just working around this issue silently.

@yandoldonov are you also using AWS Cognito and 'AddOpenIdConnect'

phcd30 avatar Mar 02 '23 12:03 phcd30

Unfortunately my company had to skip Blazor because of this issue. As a CTO, I cannot afford to rely on "authorize everything + deny specific pages only" if you take security seriously.

Previously I've also offered help to fix this for .NET in general, but as you can see on the conversation history, it didn't go well.

We're looking forward to Blazor authentication story improvements. Until then, we'll use other technologies.

dgiagio avatar Mar 02 '23 18:03 dgiagio

You could take the approach of having different servers and have them redirect. I do that between server side and client side to have best of both world. Looks like that's future as well

Get Outlook for iOShttps://aka.ms/o0ukef


From: Diego Giagio @.> Sent: Thursday, March 2, 2023 10:39:55 AM To: dotnet/aspnetcore @.> Cc: MetaHex @.>; Mention @.> Subject: Re: [dotnet/aspnetcore] Blazor Server Side AADB2C AllowAnonymous Not working in latest template (Issue #39321)

Unfortunately my company had to skip Blazor because of this issue. As a CTO, I cannot afford to rely on "authorize everything + deny specific pages only" if you take security seriously.

Previously I've also offered help to fix this for .NET in general, but as you can see on the conversation history, it didn't go well.

We're looking forward to Blazor authentication story improvements. Until then, we'll use other technologies.

β€” Reply to this email directly, view it on GitHubhttps://github.com/dotnet/aspnetcore/issues/39321#issuecomment-1452362296, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AWOI5HJYNRU7F37PD77CLMDW2DSPXANCNFSM5LKK3NZQ. You are receiving this because you were mentioned.Message ID: @.***>

MetaHex avatar Mar 03 '23 01:03 MetaHex

@yandoldonov You can put the @attribute [Authorize] directive within an _Imports.razor file in the Pages directory and that way you would avoid having to set it on every page.

That + AllowAnonymous on the _Host.cshtml should do what you want (I believe).

javiercn avatar Mar 29 '23 18:03 javiercn

Hi javier, i think the original ask was [allowanonymous] was broken. I haven’t tested on the latest.

Get Outlook for iOShttps://aka.ms/o0ukef


From: Javier Calvarro Nelson @.> Sent: Wednesday, March 29, 2023 12:00:12 PM To: dotnet/aspnetcore @.> Cc: MetaHex @.>; Mention @.> Subject: Re: [dotnet/aspnetcore] Blazor Server Side AADB2C AllowAnonymous Not working in latest template (Issue #39321)

@yandoldonovhttps://github.com/yandoldonov You can put the @attribute [Authorize] directive within an _Imports.razor file in the Pages directory and that way you would avoid having to set it on every page.

That + AllowAnonymous on the _Host.cshtml should do what you want (I believe).

β€” Reply to this email directly, view it on GitHubhttps://github.com/dotnet/aspnetcore/issues/39321#issuecomment-1489142709, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AWOI5HNLMTQ2HB3OK7J6MYTW6SBDZANCNFSM5LKK3NZQ. You are receiving this because you were mentioned.Message ID: @.***>

MetaHex avatar Mar 29 '23 19:03 MetaHex

The solution I found for this problem was to remove the fallback policy and instead implement authorization on the root folder of the project. My understanding is that the fallback policy applies the specified policy to every page where no policy was set as an override. By adding the default authorization to the root of the project, it achieves the same. The difference? The AllowAnonymous attribute is taken into account!

builder.Services.AddRazorPages(options => { options.Conventions.AuthorizeFolder("/"); });

I also needed to create a _Host_Public with the [AllowAnonymous] and a PublicApp.razor to skip getting the auth tokens. These are implement using a app.MapFallbackToPage(pattern, "/_Host_Public") This also allowed me to define a different template for public pages.

EDIT: After further testing, I am not sure how the folder authorization works. So I instead replaced the Fallback Policy by adding an [Authorize] attribute on the "_Host.cshtml". Together with the app.MapFallbackToPage("/_Host");, this ensures that every page will be authorized expect ones we explicitly map to the "_Host_Public.cshtml". Again, without a Fallback Policy, the [AllowAnonymous] attribute is honored. Any over specification of authorization using @attribute [Authorize(Policy = "potatoPolicy") is also honored (As it was using the fallback policy).

abuche-cyclops avatar Aug 22 '23 17:08 abuche-cyclops

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

ghost avatar Oct 06 '23 17:10 ghost

Are you absolutely sure this is moved to .NET 9? I just installed .NET 8 (rc2), created a new Blazor Server app, set it up with OIDC and FallbackPolicy and suddenly AllowAnonymous started working again!

gthvidsten avatar Oct 24 '23 20:10 gthvidsten

Closing as it seems this has also been addressed in .NET 8 (as part of some other work, potentially πŸ‘ )

mkArtakMSFT avatar Dec 12 '23 18:12 mkArtakMSFT