在asp.net核心中使用返回URL

时间:2017-08-22 05:15:29

标签: c# asp.net-mvc asp.net-core asp.net-core-mvc asp.net-identity

如果用户在访问特定URL时未经过身份验证/授权,我们正尝试将用户(使用返回URL)重定向到登录页面。但是,在将用户重定向到登录页面时,我们无法在路由中添加自定义参数(在本例中为clientname)。我们正在使用asp.net身份核心框架。

Startup.cs 中,我们定义了适用于所有人的以下路线。

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "Edge",
                    template: "{clientname}/{controller}/{action}");
            });

还在代码行下面添加,以确保所有URL都需要身份验证

services.AddMvc(o =>
{
   o.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));
})

并将IdentityOptions配置为重定向到登录页面,如下所示

services.Configure<IdentityOptions>(opt =>
{
  opt.Cookies.ApplicationCookie.LoginPath = new PathString("/Account/Login");
});

并且在下面的帐户控制器中是登录方法

[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl = null)
{
    this.ViewData["ReturnUrl"] = returnUrl;
    return View();
}

如果用户尝试访问任何未经身份验证的URL,则应重定向到登录页面。以Home Controller的Index方法为例。

public IActionResult Index()
{
    return View();
}

但是每当我们尝试将用户重定向到登录页面时,它都不会在URL中附加客户端名称。它形成在/Account/Login

中缺少clientname的URL下方
http://localhost:5002/Account/Login?ReturnUrl=/ClientA/home/index

因此,它导致404页面找不到错误。所以我们需要做哪些更改才能正确重定向。

网址应如下形成

http://localhost:5002/ClientA/Account/Login?ReturnUrl=/ClientA/home/index

3 个答案:

答案 0 :(得分:6)

您专门为身份验证选项设置LoginPath。默认情况下,无论您尝试访问哪种资源,它都会在您未经身份验证时始终指向您。我相信您可能必须替换或继承/覆盖一些内部,以使LoginPath基于您请求的资源而动态。我不确定是否原生支持动态LoginPaths?我错了。

在不相关的安全说明中,您应该在尝试使用之前验证ReturnUrl中的资源是否为您的应用程序的本地资源,甚至可以返回应用程序的主页。否则,格式错误的URL可能会将重定向位置欺骗为资源,该资源旨在模仿外观中的真实资源,但具有恶意意图。

// database is passed as a parameter; assume it's PDO:
// $db = new PDO("mssql:host=db_host;dbname=db_name");
// ID is also passed to the function instead of using a global

function manualDIRECTimg($db, $id) {
    $sql    = "EXECUTE spWEBSelectFoto ?, 1";
    $params = array($id);
    $stmt   = $db->prepare($sql, $params);
    $stmt->exec();
    if ($img = $stmt->fetchColumn()) {
        // Are all of these images guaranteed to be PNG?
        // If not you'll need to adjust this as needed
        header("Content-Type: image/png");
        echo $img;
        return true;
    }    
    return false;
}

答案 1 :(得分:4)

似乎他们在.Net Core MVC中进行了更改

它如何为我工作:

public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = "")
{
    ....... other codes

    if (!String.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
       return Redirect(returnUrl);
    else
       return RedirectToAction("Index", "Home");
}

现在转到HTML Razor代码:

@{
    ViewData["Title"] = "Login";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var returnUrl = @Context.Request.Query["returnurl"];
}

<form asp-action="Login" asp-route-returnurl="@returnUrl">
   <!--Rest of your login page HTML -->
</form>

现在可以正常工作了!

答案 2 :(得分:0)

您可以使用Events来获取请求并重定向到您想要的本示例中的网址。

services.ConfigureApplicationCookie(options => {

            options.Events = new Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents
            {
                OnRedirectToLogin = ctx =>
                {
                    var requestPath = ctx.Request.Path;
                    if (requestPath.Value == "/Home/About")
                    {
                        ctx.Response.Redirect("/Home/UserLogin");
                    }
                    else if (requestPath.Value == "/Home/Contact")
                    {
                        ctx.Response.Redirect("/Home/AdminLogin");
                    }

                    return Task.CompletedTask;
                }
            };

        });

查看此链接:How to redirect access denied login based on the URL on ASP.NET Core 2 Identity?