U4-9081 - Cannot Preview Content Until Published in Umbraco v7.5.2

Created by Tom Glenn 19 Oct 2016, 09:42:35 Updated by Shannon Deminick 31 Aug 2017, 04:34:05

Tags: Prioritize

Relates to: U4-10369

'''What did you do?''' Tried to preview content before publishing.

'''What did you expect to happen?''' Previewing content that has been saved but not yet published should allow you to see a preview of what that content will look like in the assigned default template.

'''What actually happened?''' Umbraco returns a 404 when clicking Preview if the content has not yet been published. Also, once the content has been published and Preview begins to work, making changes to the content, saving and then pressing Preview again will not show the latest changes. Those changes must also be published before they appear in the Preview.

I have successfully reproduced this bug in 2 different installations of Umbraco 7.

'''Reproduction steps'''

  • Create a brand new doc type
  • Create a content node of said doc type
  • Try to preview it - 404
  • Publish it then preview it again - works
  • Unpublish it and preview again - 404

2 Attachments

Download Startup.txt

Download UmbracoAuthTokenServerExtensions.txt

Comments

Sebastiaan Janssen 19 Oct 2016, 10:49:01

I've just tested this on a fairly clean install of 7.5.3 (essentially the same as 7.5.2, we didn't change any previewing). I can't reproduce any of these problems I'm afraid.

If you have additional steps to repro, we're all ears!!


Steve Farron 19 Oct 2016, 15:40:09

We are seeing this issue as well in 7.5.0 and 7.5.3. We've tried this on a clean install, but couldn't reproduce it there. We're attempting to narrow down the cause to a config or customization so we'll post here if can.


Steve Farron 20 Oct 2016, 15:35:35

I've narrowed the issue down: We're using a 3rd party Owin membership provider (can be found here: https://github.com/Bitmapped/UmbBackofficeMembershipProvider - we're basically using it stock with relevant configs changed). This was to integrate with our Active Directory. When I switch this back to the default owin:appStartup (UmbracoDefaultOwinStartup) configuration, I magically get the preview functionality back.

@tomeglenn, are you doing this as well? What does your owin:appStartup config look like?

@sebastiaan, is this enough to reproduce?


Tom Glenn 21 Oct 2016, 08:45:09

@sfarron @sebastiaan Custom Owin might be the key. We are using the UmbracoAuthTokenServerExtensions (source below) extension method: app.UseUmbracoBackOfficeTokenAuth(new BackOfficeAuthServerProviderOptions())

https://github.com/umbraco/UmbracoIdentityExtensions/blob/master/src/Umbraco.IdentityExtensions/App_Start/UmbracoAuthTokenServerExtensions.cs.pp


Tom Glenn 24 Oct 2016, 09:19:14

@sebastiaan I have narrowed it down to this line in my custom Umbraco OWIN startup.

app.UseUmbracoBackOfficeCookieAuthentication(ApplicationContext.Current);

Can you replicate with this?


Tom Glenn 22 Nov 2016, 11:39:50

@sebastiaan Any chance of an update on this issue?


Bach Huong 08 Dec 2016, 04:01:14

Hi @sebastiaan and @tomeglenn

I can reproduce this issue too with Umbraco 7.5.4 when I register my custom OwinStartup. See below the code:

[assembly: OwinStartup("CustomOwinStartup", typeof(Thomas.Umbraco.Web.CustomOwinStartup))]

namespace Thomas.Umbraco.Web { public class CustomOwinStartup : UmbracoDefaultOwinStartup { public override void Configuration(IAppBuilder app) { //ensure the default options are configured base.Configuration(app);

        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
        app.SetUmbracoLoggerFactory();

        CustomOwinStartup.ConfigureUserManagerForUmbracoBackOffice(app, ApplicationContext.Current, MembershipProviderExtensions.GetUsersMembershipProvider().AsUmbracoMembershipProvider());
        app.UseUmbracoBackOfficeCookieAuthentication(ApplicationContext.Current).UseUmbracoBackOfficeExternalCookieAuthentication(ApplicationContext.Current);
    }

    private static void ConfigureUserManagerForUmbracoBackOffice(IAppBuilder app, ApplicationContext appContext, MembershipProviderBase userMembershipProvider)
    {
        if (appContext == null)
        {
            throw new ArgumentNullException("appContext");
        }
        if (userMembershipProvider == null)
        {
            throw new ArgumentNullException("userMembershipProvider");
        }
        if (appContext.IsUpgrading || appContext.IsConfigured)
        {
            app.CreatePerOwinContext<BackOfficeUserManager>((options, owinContext) => BackOfficeUserManager.Create(options, appContext.Services.UserService, appContext.Services.ExternalLoginService, userMembershipProvider));
            app.CreatePerOwinContext<BackOfficeSignInManager>((options, context) => LdapUserSignInManager.Create(options, context, app.CreateLogger<BackOfficeSignInManager>()));
        }
    }

}

}

Is there something wrong with my setup ? I completely based on the way of Umbraco to build it, and it has been working very well since Umbraco 7.3.1 until I upgraded to the latest 7.5.4. Roll the OwinStartup back to UmbracoDefaultOwinStartup, the preview functionality is back too.

Could you please take a look and help us to overcome this serious issue?

Regards, Bach Huong


Tom Glenn 08 Dec 2016, 09:15:38

@huongcongbach There's nothing wrong with your setup, except that you're using the line which I suspected to be the root cause.

app.UseUmbracoBackOfficeCookieAuthentication(ApplicationContext.Current)

@sebastiaan If you are unable to assist with this issue, please could you assign it to someone who can? It's gaining quite a bit of traction now and it's clearly an issue.


Bach Huong 08 Dec 2016, 09:37:12

Hi @tomeglenn

I found the way to manage this work with my custom OwinStartup. I would like to share my code for you to see:

[assembly: OwinStartup("ThomasOwinStartup", typeof(ThomasOwinStartup))]

namespace Thomas.Umbraco.Web { public class ThomasOwinStartup : UmbracoDefaultOwinStartup { public override void Configuration(IAppBuilder app) { //ensure the default options are configured base.Configuration(app);

        if (ApplicationContext == null)
        {
            return;
        }
        if (MembershipProviderExtensions.GetUsersMembershipProvider().AsUmbracoMembershipProvider() == null)
        {
            return;
        }

        app.CreatePerOwinContext<BackOfficeSignInManager>((options, context) => LdapUserSignInManager.Create(options, context, app.CreateLogger<BackOfficeSignInManager>()));
    }
}

}

By this way I can register my LdapUserSignInManager in a right way, and both SSO via Active Directory and Preview functionality works either.

The root cause is that Umbraco 7.5.x has modified some key things in their UmbracoDefaultOwinStartup. See this:

Hope this helps you.

Regards, Bach Huong


Tom Bille 19 Dec 2016, 08:14:03

Huong @huongcongbach

Hi, Bach Huong. Do you know how to do this when using a custom membership provider, that is not fetching users from AD , but from our own custom database?

Thanks!


Simon Dingley 23 Jan 2017, 13:34:42

I have what appears to be the same symptoms but without any custom OwinStartup?


Bach Huong 24 Jan 2017, 04:56:52

Hi @tomeglenn

That is possible. You just need to implement the logic to fetch user's credentials from your own database inside the YourOwnUserSignInManager class. Moreover you can synchronize your user records into Umbraco users too.

Thanks!


Brian Powell 10 Mar 2017, 00:30:00

For those of you using UmbBackofficeMembershipProvider, version 3.0.0 is now posted on Github/Nuget/OurUmbraco that addresses the preview issue.


Bradley Kronson 10 Apr 2017, 14:18:57

I'm seeing this in Umbraco 7.5.11 with no custom membership provider. Any piece of content that has not been published and then previewed returns a 404


Mathieu St-Gelais 10 Apr 2017, 15:08:41

@abacus Same for me in 7.5.10.


Alan Thom 24 Apr 2017, 16:25:37

@sebastiaan @abacus @mstgelais I've just come across this issue as well using a custom owin startup on 7.5.8. After a lot of digging, my solution was to explicitly change the link from /umbraco/preview/?id=1234 to /umbraco/preview/index.html?id=1234 in the umbraco.controller.js (around line 4990).

I'd be interested to see if this resolves the issue for other people as well?

Reference: https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/74076-preview-backoffice-route-returning-a-404-error


Bradley Kronson 25 Apr 2017, 09:19:17

@alanwthom still 404s for me


Arjan Woldring 25 Apr 2017, 11:09:24

I do have problems with Preview too. Preview only works after a publish. I'm using 7.5.13 and do have also a customOwinStartup.

My implementation is as described in the umbraco documentation here: https://our.umbraco.org/documentation/Reference/Security/#replacing-the-basic-username-password-check

I only needed to replace the username/password check so that I could make a async Webservice call if the login succeed. So in my case nothing really fancy. But preview is not working...if I change back to builtin "UmbracoDefaultOwinStartup" all is good.

Any help would be great! Thanks!

edit: I was reading my post and was thinking 'okay I need to clarify what "is not working" means. I do not have a 404 error. I do see the preview canvas but the content does not get updated. So if I have a RTE and change some text and click on 'Preview' it does not reflect in the preview-canvas.


Shannon Deminick 20 Jun 2017, 01:35:30

Very important, if you have a custom Owin startup and are inheriting from UmbracoDefaultOwinStartup and you override ConfigureMiddleware, it is critical that you call base.ConfigureMiddleware, similarly if you are just overriding Configuration it is critical that you call base.Configuration (but it is recommended to not override that method and you should override ConfigureMiddleware and ConfigureServices where necessary

If you are using a 100% custom startup owin then you absolutely must call all of the required methods to boot umbraco, all of this logic must still be executing:


Bradley Kronson 20 Jun 2017, 05:23:16

@Shandem not sure how this helps those of us who are not running a custom Owin implementation and experiencing the problem?


Shannon Deminick 20 Jun 2017, 05:54:35

Perhaps it doesn't, I'm just pointing out some important information for those that might be


Bradley Kronson 20 Jun 2017, 06:02:54

@Shandem thanks ;)


Ben Sapp 28 Aug 2017, 23:56:21

@Shandem this solved this problem for us. It is not really a problem with Umbraco as much as it is with the security documentation.

Per https://our.umbraco.org/documentation/Reference/Security/, Under "Replacing the basic username/password check" step 3, it asks you to modify "~/App_Start/UmbracoCustomOwinStartup.cs" to configure ActiveDirectoryBackOfficeUserPasswordChecker.

The UmbracoCustomOwinStartup.cs file (https://github.com/umbraco/UmbracoIdentityExtensions/blob/master/src/Umbraco.IdentityExtensions/App_Start/UmbracoCustomOwinStartup.cs.pp) does not call base.Configuration so app.UseUmbracoPreviewAuthentication is never called.

Calling base.Configuration and then calling app.ConfigureUserManagerForUmbracoBackOffice solved the problem for us.

If the security documentation under "Authenticating with Active Directory credentials" directed you to add code to "/App_Start/UmbracoStandardOwinStartup.cs" instead of "/App_Start/UmbracoCustomOwinStartup.cs" (and to leave in the call to base.Configuration) it would avoid this pitfall.


Shannon Deminick 29 Aug 2017, 00:14:32

Hi @hal9000 any chance you'd be able to create a PR with the update info? The docs live here: https://github.com/umbraco/UmbracoDocs/blob/master/Reference/Security/index.md


Brian Powell 29 Aug 2017, 13:24:01

In my code, I have my UmbracoCustomOwinStartup inherit from UmbracoDefaultOwinStartup. I just override the ConfigureServices method with my custom user manager. I have two suggestions:

Would it make sense to realign UmbracoCustomOwinStartup so it uses the same methods as UmbracoDefaultOwinStartup? That way, users could just override the stuff they need to change and would continue to pick up the rest of the default settings. Right now, the custom code is a full reimplementation of the class.

In UmbracoDefaultOwinStartup, can the user manager configuration in ConfigureServices() be broken out into its own method? This would make it easy to just override that section of code while continuing to pick up the rest of the default settings.


Ben Sapp 29 Aug 2017, 16:16:25

@Shandem sure I can do that.


Shannon Deminick 30 Aug 2017, 01:03:15

@bitmapped I've updated the Core UmbracoDefaultOwinStartup to have a virtual ConfigureUmbracoUserManager method: https://github.com/umbraco/Umbraco-CMS/commit/8c998fd4e663a4ff6066d6a55207862e3c83aa4a

Both UmbracoStandardOwinStartup and UmbracoCustomOwinStartup are code snippets that are part of IdentityExtensions: *https://github.com/umbraco/UmbracoIdentityExtensions/blob/master/src/Umbraco.IdentityExtensions/App_Start/UmbracoStandardOwinStartup.cs.pp *https://github.com/umbraco/UmbracoIdentityExtensions/blob/master/src/Umbraco.IdentityExtensions/App_Start/UmbracoCustomOwinStartup.cs.pp

These can certainly be updated, however ... a new major version release of IdentityExtensions would need to be made since the ConfigureServices and ConfigureMiddleware methods on the UmbracoDefaultOwinStartup are not available on Umbraco 7.3.0 which is the min version that this nuget package targets currently. Could you do a PR?


Brian Powell 30 Aug 2017, 03:14:21

@Shandem Thanks for splitting out {{ConfigureUmbracoUserManager}}. I'll put together a pull request for IdentityExtensions, probably tomorrow.


Brian Powell 31 Aug 2017, 00:14:38

@Shandem After trying to figure out why Facebook/Google OAuth providers would appear and the OAuth calls occurred but Umbraco would never link or allow logins, I realized that the configuration for the OAuth providers needs to happen after ConfigureMiddleware runs. It doesn't seem to me that ConfigureMiddleware is a logical place for users to be overriding for this purpose, so I've put together a PR at https://github.com/umbraco/Umbraco-CMS/pull/2162 that adds a new ConfigureExternalLogins method that runs after ConfigureMiddleware. Users can configure OAuth providers by overriding that method.

The question becomes what to do with UmbracoIdentityExtensions. In order to get the benefit of the restructuring to make things more sensible, we'd need to jump the dependency requirements all the way forward to now. What are your thoughts?


Shannon Deminick 31 Aug 2017, 04:34:05

@bitmapped I've created a separate issue to track this and discuss this here http://issues.umbraco.org/issue/U4-10369


Priority: Normal

Type: Bug

State: Open

Assignee: Sebastiaan Janssen

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted:

Affected versions: 7.5.2, 7.5.4, 7.5.10, 7.5.11, 7.5.13

Due in version:

Sprint:

Story Points:

Cycle: