问题描述
我正在研究此处提供的示例:
- Use cookie authentication without ASP.NET Core Identity
- AspNetCore.Docs/aspnetcore/security/authentication/cookie/samples/3.x/CookieSample/
而且我正在尝试在我自己的应用中实现类似的功能。示例应用的大部分功能都在我的应用中复制,但有一个关键功能不起作用。
在此示例应用程序中,有一个“联系人(需要身份验证)”链接,单击该链接时会加载“/联系人”页面 - 如果用户已登录。
如果用户未登录,“Contact (Authentication required)”链接的 href= 仍然设置为“/Contact”,但是当您点击它时,您最终会进入“/Account/Login”控制器,将 ReturnUrl 设置为“/Contact”。
“主页”链接指向 Index.cshtml,如果用户未登录,则不会重定向到 /Account/Login 。
这一切都很普通,除了...我找不到重定向到 /Account/Login 的位置,而且我无法确定为什么我们重定向到一个页面而不是另一个页面。
是什么导致 Contact 重定向到 Login 而 Home 不重定向,我应该在哪里配置它是我想要重定向到的 Account/Login?
Rakib 的评论将我引向了一个 YouTube 视频,同一系列中较早的一个视频提示了我的一个问题。
ConfigureServices() 中的示例应用具有:
services.AddRazorPages(options =>
{
options.Conventions.AuthorizePage("/Contact");
});
这就是“/Contact”需要身份验证的原因。但是我还是没看明白是什么设置了“/Account/Login”作为需要认证时的URL。
解决方法
第 1 部分
是什么导致 Contact 重定向到 Login 而 Home 不重定向?
- 如果页面或控制器配置为允许匿名,则不会重定向到登录
[AllowAnonymous]
public class HomePage : PageModel
{
//...
}
- 如果页面/文件夹或区域仅配置给授权用户,通过
[Authorize]
属性或在startup.cs
中,如果用户未登录,它将重定向到登录页面。立>
[Authorize]
public ContactModel : PageModel
{
// ...
}
以下是启动时授权的示例配置,我们为角色名称 RequireAdmins
创建了一个名为 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 部分
我应该在哪里配置它是我想要重定向到的帐户/登录名?
配置可以在启动时完成,一般我会创建一个自定义的认证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;
});