umbraco / Umbraco-CMS

Umbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.
https://umbraco.com
MIT License
4.45k stars 2.68k forks source link

Models builder and UmbracoContext return different IPublishedContent on the login page #12312

Open Myster opened 2 years ago

Myster commented 2 years ago

Umbraco version

9.4.3

Bug summary

Given you are using PublicAccess to restrict access & specify a login page. When you hit a restricted page When not logged in. Then the view returns different IPublishedContent based on which method you use to retrieve it.

Specifics

The page we're viewing (both the denied and login page) has this view:

@using Umbraco.Cms.Core.Web
@inherits UmbracoViewPage<DetailPage>
@inject IUmbracoContextAccessor umbracoContext

@{ 
    var currentPage = Model.Unwrap();
    var publishedContent = umbracoContext.GetRequiredUmbracoContext().PublishedRequest.PublishedContent;
}
<p>Model.Unwrap().Url = @(Model.Unwrap().Url())</p>
<p>publishedContent.Url = @publishedContent.Url();</p>

The output is:

Model.Unwrap().Url = /login/ publishedContent.Url = /restricted/

Note: if you use any partials that use publishedContent from the 'context' rather than models builder it will show restricted content when you are not logged in.

Expected result / actual result

I expect both methods to return the IPublishedContent for /login/

Myster commented 2 years ago

Is there a way to make the login system 'redirect' to a login page instead of 'rewrite' the current URL?

nul800sebastiaan commented 2 years ago

No there's nothing built in for that and changing the behavior now would be a breaking change for people relying on the existing behavior.

As a workaround you could probably do your own redirects from the template by detecting IsProtected and checking if they're logged in. Not sure. Of course it's also possible to bypass the built-in public access feature and replace it with your own.

I'll ask if / how we could update the public access feature.

Myster commented 2 years ago

The primary issue is not really the rewrite vs redirect, that was just how I was thinking of working around the issue.

jattwood commented 1 year ago

I have been wrestling with this issue all day. Of course I inadvertently created a duplicate before stumbling on this one:

https://github.com/umbraco/Umbraco-CMS/issues/13462

There are more details that may be relevant there, but in short my issue is that my view components are all returning restricted content because the login page and the restricted page share some of the same view components. If I use:

var currentPage = _context.GetRequiredUmbracoContext().PublishedRequest.PublishedContent;

To resolve the current page in the VC I end up not with the login page, but restricted content page. [UmbracoMemberAuthorize] does not work in VC controllers.

The published request needs to get updated when login is triggered as it's not currently cascading down in the context.

The frustrating part is that if I use [UmbracoMemberAuthorize] the default behavior is a redirect, but if I use public access it's more like a rewrite. That behavior should be more consistent. Redirect like the good 'ol days would be a better option IMO and address the context issue at the same time. Maybe implemented as as a configurable option...

Thank you!

Jamie