Shazwazza / UmbracoIdentity

ASP.NET Identity implementation for Umbraco's native member data
MIT License
111 stars 58 forks source link

Unpublished Pages Throw 404 on Preview #113

Closed sinkypars1885 closed 4 years ago

sinkypars1885 commented 4 years ago

Using the latest nuget package (7.1), upon previewing unpublished pages a 404 is thrown.

This is on Umbraco 8.6.

Any help is much appreciated.

Shazwazza commented 4 years ago

Sounds like a preview authentication issue which could be caused by an ordering of OWIN things. Preview authentication for Umbraco is done with a call to UseUmbracoPreviewAuthentication what does your owin startup file look like?

sinkypars1885 commented 4 years ago

` public class UmbracoIdentityOwinStartup : UmbracoIdentityOwinStartupBase { protected override void ConfigureUmbracoUserManager(IAppBuilder app) { base.ConfigureUmbracoUserManager(app);

        //Single method to configure the Identity user manager for use with Umbraco
        app.ConfigureUserManagerForUmbracoMembers<UmbracoApplicationMember>();

        //Single method to configure the Identity user manager for use with Umbraco
        app.ConfigureRoleManagerForUmbracoMembers<UmbracoApplicationRole>();
    }

    protected override void ConfigureMiddleware(IAppBuilder app)
    {

        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        base.ConfigureMiddleware(app);
    }

    protected override void ConfigureUmbracoAuthentication(IAppBuilder app)
    {
        base.ConfigureUmbracoAuthentication(app);

        var cookieOptions = CreateFrontEndCookieAuthenticationOptions();

        cookieOptions.ExpireTimeSpan = TimeSpan.FromDays(20);

        cookieOptions.Provider = new CookieAuthenticationProvider
        {

            OnValidateIdentity = SecurityStampValidator
                    .OnValidateIdentity<UmbracoMembersUserManager<UmbracoApplicationMember>, UmbracoApplicationMember, int>(
                        TimeSpan.FromMinutes(30),
                        (manager, user) => user.GenerateUserIdentityAsync(manager),
                        identity => identity.GetUserId<int>())
        };

        app.UseCookieAuthentication(cookieOptions, PipelineStage.Authenticate);

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        app.UseFacebookAuthentication(appId: "XXX", appSecret: "XXX");

        app.UseLinkedInAuthentication("XXX", "XXX");

    }
}`

Does that help?

jpiombo commented 4 years ago

I saw a preview issue as well, resolving by placing: base.ConfigureUmbracoAuthentication(app); after MY code. Not sure if it's ideal, but it all keep working AND preview started working again.

sinkypars1885 commented 4 years ago

Like this?

` protected override void ConfigureUmbracoAuthentication(IAppBuilder app) {

    var cookieOptions = CreateFrontEndCookieAuthenticationOptions();

    cookieOptions.ExpireTimeSpan = TimeSpan.FromDays(20);

    cookieOptions.Provider = new CookieAuthenticationProvider
    {

        OnValidateIdentity = SecurityStampValidator
                .OnValidateIdentity<UmbracoMembersUserManager<UmbracoApplicationMember>, UmbracoApplicationMember, int>(
                    TimeSpan.FromMinutes(30),
                    (manager, user) => user.GenerateUserIdentityAsync(manager),
                    identity => identity.GetUserId<int>())
    };

    app.UseCookieAuthentication(cookieOptions, PipelineStage.Authenticate);

    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    app.UseFacebookAuthentication(appId: "XXX", appSecret: "XXX");

    app.UseLinkedInAuthentication("XXX", "XXX");
    base.ConfigureUmbracoAuthentication(app);

}`

This does not let me preview unpublished pages unfortunately.

Shazwazza commented 4 years ago

Hi all, yes the ordering of things is important and can be annoying/complex. This is also related https://github.com/umbraco/UmbracoIdentityExtensions/pull/39.

resolving by placing: base.ConfigureUmbracoAuthentication(app); after MY code. Not sure if it's ideal, but it all keep working AND preview started working again.

This can be because of various things and depends on the OAuth provider being implemented. The default OWIN startup looks like this for this phase https://github.com/umbraco/Umbraco-CMS/blob/v8/contrib/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs#L95

As you can see, preview auth happens last and it is also explicitly designated to the PipelineStage.Authorize stage which is after the PipelineStage.Authenticate phase.

If you override this method and call base.ConfigureUmbracoAuthentication(app); first (like you probably would since that is a default practice) then it could mean that your middleware may execute before the preview middleware but the preview middleware must execute after. So ordering here is important. You have some options, you can either copy the default implementation and call the various Use methods manually, or you can re-order how you call your own middleware options like changing where the base implementation is called, or you can change your middleware to be explicitly registered to the PipelineStage.Authenticate, some oauth middlewares have this option built in, others do not (like openidconnect) where you'd have to manually apply the app.UseStageMarker(PipelineStage.Authenticate) code call. Unfortunately some of this will be trial and error until you get the ordering right since it all depends on how you've setup your startup code which can be totally different from install to install.

Shazwazza commented 4 years ago

Also note the rules about stage markers: https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline#stage-marker-rules since that can have different affects than one might think.