IdentityServer4 How can I redirect after login to

2019-08-17 07:33发布

问题:

As recommend I would have register the authorize callback url/redirect_url at IdP, which it works.

But what if a client using MVC app tries to access a page with an unauthorized state, will be redirect to idsrv login page.

The redirect_url is always (Home page entry point) as configured.

To change this behavior I would have to register all possible routes at IdP. That can not a be solution!

On idsrv Login method I have tried:

Login(string returnUrl)

checking the value from returnUrl it gives /connect/authorize/callback?client_id=...

Shouldn't returnUrl have the url of the previous page? Like in a normal mvc app has..

I have tried to get Referer store it on session and then redirect..

 if (!string.IsNullOrEmpty(Request.Headers["Referer"].ToString()))
 {
      this.httpContextAccessor.HttpContext.Session.SetString("Referer", Request.Headers["Referer"].ToString());
 }

But that doesn't work Referer comes null...

I have checked what's coming on context from interation services

var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
                        context.RedirectUri

And returns /signin-oidc/ this is the automated way for returning (Home page entry point).

Any chance to get the previous url, so that the user can be redirect?

So what can I do else?

I'm using Hybrid flow to manage the following clients : mvc-app, classic-asp, web api

回答1:

Here's an example of implementation allowing you to achieve what you want. Keep in mind that there's other ways of doing it.

All the code goes on your client, the server never knows anything about the end url.

First, you want to create a custom attribute that will be decorating all your actions/controllers that you want to protect:

using System;
using System.Web.Mvc;

namespace MyApp
{
    internal class MyCustomAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext.Result is HttpUnauthorizedResult)
            {
              filterContext.RequestContext.HttpContext.Session["oidc-returnUrl"] = filterContext.RequestContext.HttpContext.Request.UrlReferrer?.PathAndQuery;
            }
        }
    }
}

And then you are going to create a login route/action that will handle all your authorize requests:

using System.Web.Mvc;

namespace MyApp
{
    public class AccountController : Controller
    {
        [MyCustomAuthorize]
        public ActionResult Login()
        {
            returnUrl = Session["oidc-returnUrl"]?.ToString();

            // clean up
            Session["oidc-returnUrl"] = null;

            return Redirect(returnUrl ?? "/");
        }
    }
}

The login path can be changed in your startup code:

public class Startup
{

    public void Configure(IApplicationBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            LoginPath = "/my-login"
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            // setting up your client
        });
    }
}