在ASP.NET Core中,您应在哪里配置重定向以登录?

问题描述:

我正在研究此处提供的示例:

I'm working through the example provided here:

我正在尝试在自己的应用程序中实现类似的功能.该示例应用程序所做的大部分工作都可以在我的应用程序中复制出来,但其中一项关键功能却无法实现.

And I'm trying to implement something similar in my own app. Much of what the sample app does works, as replicated in my app, but there is one critical functionality that does not.

在此示例应用程序中,有一个联系人(需要身份验证)"链接,即单击该链接可加载"/Contact"页面-如果用户已登录.

In this sample app, there is a "Contact (Authentication Required)" link, that when clicked loads the "/Contact" page - if the user is logged in.

如果用户未登录,则联系人(需要身份验证)"会显示在屏幕上.链接仍将其href =设置为"/Contact",但是当您单击该链接时,您最终会进入"/Account/Login"控制器,并将ReturnUrl设置为"/Contact".

If the user is not logged in, the "Contact (Authentication Required)" link still has its href= set to "/Contact", but when you click on it you end up in the "/Account/Login" controller, with ReturnUrl set to "/Contact".

主页"链接指向 Index.cshtml,并且重定向到/Account/Login "如果用户未登录.

The "Home" link directs to Index.cshtml, and does not redirect to /Account/Login " if the user is not logged in.

除了...之外,其他都很普通.我无法找到配置到/Account/Login的重定向的位置,也无法确定为什么要在一个页面上进行重定向,而在另一页面上却没有.

Which is all pretty ordinary, except ... I cannot find where the redirect to /Account/Login is configured, and I cannot determine why we're redirecting on one page but not the other.

是什么原因导致联系人"重定向到登录名"和主页"而不是?我该在哪里配置我要重定向到的帐户/登录名"?

What is it that causes Contact to redirect to Login and Home to not, and where do I configure that it's Account/Login that I want to redirect to?

Rakib的评论将我引向了YouTube视频,而同一系列中的较早视频则向我暗示了我的问题之一.

Rakib's comment pointed me to a YouTube video, and an earlier video in the same series gave me a hint on one of my problems.

ConfigureServices()中的示例应用程序具有:

The sample app, in ConfigureServices(), has:

services.AddRazorPages(options =>
{
    options.Conventions.AuthorizePage("/Contact");
});

这就是为什么"/联系"需要认证.但是我仍然看不到设置"/Account/Login"的原因.作为您需要身份验证时的网址.

So this is why "/Contact" requires authentication. But I still don't see what sets "/Account/Login" as the URL when you need authentication.

第1部分

是什么导致联系人"重定向到登录名"而不是首页"?

What is it that causes Contact to redirect to Login and Home to not?

  • 如果页面或控制器配置为允许匿名,则它将不会重定向到登录
[AllowAnonymous]
public class HomePage : PageModel
{
    //...
}

  • 如果页面/文件夹或区域仅配置为授权用户,则通过 [Authorize] 属性或在 startup.cs 中将其重定向到登录名如果他未登录,则显示页面.
    • If the page/folder or area is configured to authorized users only, either by [Authorize] attribute or in startup.cs it will redirect the user to the login page if he is not logged in.
[Authorize]
public ContactModel : PageModel
{
    // ...
}

这里是启动时授权的示例配置,在该示例中,我们为角色名称 Admins 创建了一个名为 RequireAdmins 的基于角色的策略:

Here is a sample configuration for authorization in startup, where we do create a role based policy named RequireAdmins for a role name Admins:

services.AddRazorPages()
    .AddRazorPagesOptions(ops =>
    {
        ops.Conventions.AuthorizeAreaFolder("Panel", "/", "RequireAdmins");
        ops.Conventions.AuthorizeFolder("/", "RequireAdmins");
        ops.Conventions.AllowAnonymousToAreaPage("Identity", "/Account/AccessDenied");
    });

services.AddAuthorization(ops =>
{
    ops.AddPolicy("RequireAdmins", policy => policy.RequireRole("Admins"));
});

第 2 部分

我应该在哪里配置我要重定向到的帐户/登录名?

where do I configure that it's Account/Login that I want to redirect to?

可以在启动时完成配置,通常我会创建一个自定义身份验证cookie:

The configuration can be done in startup, in general I do create a custom authentication cookie:

public class XCookieAuthEvents : CookieAuthenticationEvents
{
    public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> context)
    {
        context.RedirectUri = $"/Identity/Account/CustomLogin";
        return base.RedirectToLogin(context);
    }

    public override Task RedirectToLogout(RedirectContext<CookieAuthenticationOptions> context)
    {
        context.RedirectUri = $"/Identity/Account/CustomLogout";
        return base.RedirectToLogout(context);
    }

    public override Task RedirectToAccessDenied(RedirectContext<CookieAuthenticationOptions> context)
    {
        context.RedirectUri = $"/Identity/Account/CustomAccessDenied";
        return base.RedirectToAccessDenied(context);
    }

    public override Task RedirectToReturnUrl(RedirectContext<CookieAuthenticationOptions> context)
    {
        context.RedirectUri = $"/CustomReturnUrl";
        return base.RedirectToReturnUrl(context);
    }
}

然后在启动时注册:

services.AddScoped<XCookieAuthEvents>();

// optional: customize cookie expiration time
services.ConfigureApplicationCookie(ops =>
{
    ops.EventsType = typeof(XCookieAuthEvents);
    ops.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    ops.SlidingExpiration = true;
});