Try our conversational search powered by Generative AI!

Custom redirect on login based on role

Vote:
 

Hi,

We have a cms12/DXP/.Net Core 6 solution with hundreds of users each with their own subset of pages. Several Clients find it cumbersome to have to navigate the page tree from the main startpage down to their "startpage", so Im trying to implement a redirect that takes them directly there after they login. I managed to implement a solution that works locally on IIS:

From ConfigureServices of startup.cs:

services.ConfigureApplicationCookie(options =>
            {
                options.LoginPath = "/util/Login";
                options.LogoutPath = "/nb-no/logout";
                options.Events.OnSignedIn = (context) =>
                {
                    try
                    {
                        var pageId = LoginRedirectMapper.GetLoginRedirectPageId(context.Principal);
                        if (pageId > 0)
                            MemoryCache.Default.Add("Redirpage_" + context.Principal.Identity.Name, pageId, DateTime.Now.AddMinutes(1));
                    }
                    catch (Exception exp)
                    {
                        Logger.Error("Failed to set redirecturl on user-login. Message:" + exp.Message + "\r\nStack:\r\n" + exp.StackTrace);
                    }
                    return Task.CompletedTask;
                };
            });

This gets the ID of the correct page to redirect to and adds it to Cache. (GetLoginRedirectPageId get's the pageid to redirect to. This works as intended, so I won't add that code.)

From Configure in startup.cs:

app.Use(async (context, next) => 
            {
                await next();
                try
                {
                    if (context.Request.Path == "/episerver/cms" && MemoryCache.Default.Contains("Redirpage_" + context.User.Identity.Name))
                    {
                        var redirPageId = (int)MemoryCache.Default.Remove("Redirpage_" + context.User.Identity.Name);
                        var url = "/episerver/cms#context=epi.cms.contentdata:///" + redirPageId + "&viewsetting=viewlanguage:///nb-NO";
                        context.Response.Redirect(url);
                    }
                }
                catch {  }
            });

This checks if there is a cache-value with pageid for the user and if so redirects to the given page.

But this doesn't work on DXP/Kestrel. The code runs as it should, but the Redirect simply doesn't happen. I suspect that Response can't be changed once next() has run.

Does anyone have any idea how I could get this working on Kestrel? Or maybe a completely different approach?

#300315
Apr 18, 2023 11:45
Vote:
 

I found a hacky way to make it work on Kestrel:

app.Use(async (context, next) => 
{
    var originalBodyStream = context.Response.Body;
    using (var responseBody = new MemoryStream())
    {
        context.Response.Body = responseBody;
        await next();
        if (context.Request.Path == "/episerver/cms" && MemoryCache.Default.Contains("Redirpage_" + context.User.Identity.Name))
        {
            context.Response.Body = originalBodyStream;
            var redirPageId = (int)MemoryCache.Default.Remove("Redirpage_" + context.User.Identity.Name);
            var url = "/episerver/cms#context=epi.cms.contentdata:///" + redirPageId + "&viewsetting=viewlanguage:///nb-NO";
            context.Response.Redirect(url);
        }
        else
        {
            responseBody.Seek(0, SeekOrigin.Begin);
            await responseBody.CopyToAsync(originalBodyStream);
            context.Response.Body = originalBodyStream;
        }
    }
});

I basically feed the next middleware a fake Response.Body to get it to set the User-Identity. When I reset the Body Im still allowed to modify the Response. But Im not sure if I want to use such a hacky solution, so I'd appreacate if anyone has a better solution.

#300318
Apr 18, 2023 13:16
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.