volume_up

A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

volume_up

A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Redirect in Controller after Authentication

Hi folks,

We have a custom login page in place, quite similar to this one here.

We would like to redirect users to the backend, to be precise to "/EPiServer/CMS".

Currently, the code in the CustomLoginController looks like this:

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        public ActionResult LocalLogin(CustomLoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                bool result = uiSignInManager.SignIn(uiUserProvider.Name, model.Username, model.Password);

                if (result)
                {
                    return Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage));
                }
            }

            ModelState.AddModelError("LoginError", "Login failed");

            return View(Global.CustomLoginView, model);
        }

So we tried different things here to actually redirect to the backend but whatever we do we always get redirected to the StartPage / index page. Things we have tried:

return Redirect(UrlResolver.Current.GetUrl("/EPiServer/CMS"));

return Redirect("/EPiServer/CMS");

//Even those two get ignored and users get redirected to the StartPage

return Redirect("WHATEVER");

return Redirect("http://www.google.com");

Any ideas what we are doing wrong?

Best regards,

Patrick

#196619
Sep 05, 2018 16:58

Sounds strange, can you post a version of the full code that still redirects to start page but shouldn't?

When I tested it worked fine redirecting to /episerver/cms using this test code:

Action:

[HttpPost]
public ActionResult TestRedirect()
{
    return Redirect("/episerver/cms");
}

View:

<div>
    @using (Html.BeginForm("TestRedirect", "Test", FormMethod.Post))
    {
        <button type="submit">Test</button>
    }
</div>

(I'm already logged in when doing this, but the outcome should be the same regardless of when you login the user.)

#196634
Edited, Sep 05, 2018 23:38

Here is the full monty.

View:

    <div class="modal">
            @using (Html.BeginForm("LocalLogin", "CustomLogin", FormMethod.Post))
            {
                @Html.AntiForgeryToken()

                <ol class="clearfix">
                    <li>
                        <img src="/util/images/login/DXC_long.svg" alt="logo" class="logo" />
                    </li>
                    <li>
                        <div class="validation-summary text--error">
                            @Html.ValidationSummary()
                        </div>
                    </li>
                    <li>
                        @Html.LabelFor(x => x.Username)
                        @Html.TextBoxFor(x => x.Username)
                    </li>
                    <li>
                        @Html.LabelFor(x => x.Password)
                        @Html.PasswordFor(x => x.Password)
                    </li>
                    <li>
                        <input type="submit" value="Log in" class="epi-button-child-item" />
                    </li>
                    <li>
                        <p class="text--small">
                            <a "#" onclick="toggleCookieText(); return false;">
                                When you log in, cookies will be used.
                            </a>
                        </p>
                        <div id="cookieInfoPanel" class="cookie-information">
                            <p class="text--small">
                                A cookie containing login information will be sent to your web browser. If you do not want to receive cookies, you will be unable to log into the website.
                            </p>
                        </div>
                    </li>
                </ol>
            }
        </div>

Controller:

namespace A1Digital.Site.Controllers
{
    public class CustomLoginController : Controller
    {
        private UISignInManager uiSignInManager = ServiceLocator.Current.GetInstance<UISignInManager>();
        private UIUserProvider uiUserProvider = ServiceLocator.Current.GetInstance<UIUserProvider>();

        public ActionResult Index()
        {
            return View(Global.CustomLoginView);
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        public ActionResult LocalLogin(CustomLoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                bool result = uiSignInManager.SignIn(uiUserProvider.Name, model.Username, model.Password);

                if (result)
                {
                    return Redirect("/EPiServer/CMS");
                }
            }

            ModelState.AddModelError("LoginError", "Login failed");

            return View(Global.CustomLoginView, model);
        }
    }
}

Moreover, when taking a look at the network tab in the browsers console, the request points correctly to "/CustomLogin/LocalLogin" with a HTTP Status Code of "302 - Found", but the "Location" header of the response is "/".

#196654
Sep 06, 2018 10:26

If you manually visit "/episerver" after being redirected to "/", is your user considered to be logged in?

Do you have an <authentication>-element in your web.config? If you have one, what does it look like?

#196659
Sep 06, 2018 12:43

Yes, after the user is redirected to "/" he can even see the orange EPiServer menu in the upper right corner and can access the backend.

That's what the <authentication>-element looks like in our web.config:

    <authentication mode="None">
    </authentication>
#196660
Sep 06, 2018 13:16

Does this happen in a specific environment?

Can you test what happens if you use the basic redirect code I posted above? You can first login (for example through "/Util/Login.aspx").

#196668
Sep 06, 2018 15:04

So far I have only tested this on my local machine (we have the DXC subscription).

Interestingly your code works. When clicking the "Test" button, I get redirected to /episerver/cms.

#196727
Sep 10, 2018 14:10

probably late to the party and not sure if it's related, but looking at `EPiServer.Cms.UI.AspNetIdentity.ApplicationUISignInManager<TUser>` you can see that it does redirect on its own.

public override bool SignIn(string providerName, string userName, string password)
{
  string returnUrl = this.GetReturnUrl();
  if (!this._signInManager().SignIn(userName, password, returnUrl))
    return false;
  this.Redirect(returnUrl);
  return true;
}

and there is custom redirect method in that manager:

protected virtual void Redirect(string returnUrl)
{
  HttpContext current = HttpContext.Current;
  if (current == null)
    return;
  if (string.IsNullOrWhiteSpace(returnUrl))
    return;
  try
  {
    current.Response.Redirect(VirtualPathUtility.ToAbsolute(returnUrl), false);
    current.ApplicationInstance.CompleteRequest();
    current.Response.End();
  }
  catch (ThreadAbortException ex)
  {
  }
}

NB! note `currect.Response.End()` method..

and redirect url is standard aspnet query string (if present) - "?ReturnUrl=..". you can give it a try and test login process with custom redirect url just to make sure that this signin manager is not messing things up.

#196756
Sep 11, 2018 7:35

I just tried to login with the ReturnUrl parameter like "/CustomLogin?ReturnUrl=%2Fepiserver%2Fcms" but again simply got redirected to "/" undecided

#196764
Sep 11, 2018 10:04

it might be lost during post back to the controller maybe?

#196765
Sep 11, 2018 10:15

Is there a way to find this out?

#196812
Sep 12, 2018 9:53

can you add what request is being posted to the controller (can capture network traffic in dev tools for instance)?

#196947
Sep 18, 2018 9:25

LoginNetworkRequest

#196949
Sep 18, 2018 10:13

the login page is really a custom one (and just looks like built-in) or you use default epi login page?

#196952
Sep 18, 2018 10:47

Yes, this is actually a custom login page and just looks like the OOTB login page (for now ^^).

#196967
Sep 18, 2018 15:29

ok, and custom login page form containing action with "ReturnUrl" query string?

#196975
Sep 18, 2018 20:45

You can check the view here.

#196987
Edited, Sep 19, 2018 9:06
Vote:
@using (Html.BeginForm("LocalLogin", "CustomLogin", new { ReturnUrl = "http://takemehome.com" }, FormMethod.Post))

?

#197026
Sep 19, 2018 15:25
Vote:

Hello again Patrick!

I started setting up a project of my own which makes use of ASP.NET Identity. After I set it up I decided to take a proper look at solving this issue.

It was indeed the absence of ReturnUrl that caused it. The solution to this that I came up with can be found here:

https://world.episerver.com/blogs/jafet-valdez/dates/2018/9/curing-your-redirect-woes-when-using-uisigninmanager-signin/

The solution doesn't require you to set a ReturnUrl at all (if you don't want to) and it also enables you to use your OWIN configuration file to specify a redirect location when users sign in.

Hope this helps!

Thanks a lot @Valdis for pointing us in the right direction!

#197042
Edited, Sep 20, 2018 1:23

Thanks guys, with your help I was able to resolve the issue! cool

#197055
Sep 20, 2018 10:58

ah, nice. great success! I was lazy enough not to provide complete solution ;)

#197061
Sep 20, 2018 14:16
error 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.