将登录重定向到控制器操作

Redirect Login to Controller Action

从使用个人用户帐户的 ASP.NET 5 Web 应用程序模板开始,我已经设法获得使用 Microsoft 帐户的外部身份验证。当用户单击“登录”时,他们会像这样

被重定向到 AccountController 中的 ExternalLogin
<form asp-controller="Account" asp-action="ExternalLogin" method="post" asp-route-returnurl="@ViewData["ReturnUrl"]" class="nav navbar-right">
    <button type="submit" class="btn btn-null nav navbar-nav navbar-right" name="provider" value="Microsoft" title="Log in"><span class="fa fa-sign-in"/>&nbsp; Log In</button>
</form>

这让他们使用他们的 Microsoft 帐户登录,并且一切似乎都运行良好。但是我如何拦截直接访问特权操作 [Authorize] 的尝试,以便将用户重定向到 ExternalLogin?可以在 Startup.cs 中设置默认操作吗?

编辑 1 尝试遵循 @Yves 的建议,我在过滤器文件夹中创建了 CustomAutorizationFilter。它不检查任何条件

public class CustomAutorizationFilter : IAuthorizationFilter
{
    public void OnAuthorization(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
    {
        //if (...) // Check you conditions here
        //{
            context.Result = new RedirectToActionResult("ExternalLogin", "Account", null);
        //}
    }
}

并编辑了 ConfigureServices 如下

        services.AddMvc(config =>
        {
            config.Filters.Add(typeof(Filters.CustomAutorizationFilter));
        });

当我 运行 在本地应用程序时,它不再转到主页。它returns一个空白http://localhost:52711/Account/ExternalLogin

显然有很多我不明白。

编辑2:这里是ExternalLogin

的签名
 // POST: /Account/ExternalLogin
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public IActionResult ExternalLogin(string provider, string returnUrl = null)

这就是 ExternalLogin 在 ASP.Net 5 Web 应用程序模板中开箱即用的方式。

您可以注册 IAuthorizationFilterIActionFilter 实现来完成此操作。在这些过滤器中,您可以检查请求是否正在尝试访问特权操作,用户是否已登录或是否有足够的权限来执行此操作。

如果您正在使用AutorizeAttribute,我建议您使用AutorizationFilter。 如果您使用自己的自定义属性,则使用 ActionFilter.

这是一个例子:

MVC 在每个动作执行之前调用 IAuthorizationFilter.OnAuthorization 方法。

public class CustomAuthorizationFilter : IAuthorizationFilter
{
    public void OnAuthorization(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
    {
        if (...) // Check you conditions here
        {
            context.Result = new RedirectToActionResult("ExternalLogin", "Account", null);
        }
    }
}

要注册此过滤器,请在 Startup.cs 中编辑您的 ConfigureServices 方法:

services.AddMvc(config =>
{
    config.Filters.Add(typeof(CustomAuthorizationFilter ));
});

或者如果您想使用自己的属性,您可以使用 ActionFilterOnActionExecuting 方法来检查是否一切如您所愿...

因为我无法让 CustomAuthorizationFilter 按照@Yves 的建议工作,所以我求助于一个令人讨厌的 hack。我修改了AccountController Login如下

     // GET: /Account/Login
    [HttpGet]
    [AllowAnonymous]
    public IActionResult Login(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return RedirectToAction(nameof(ExternalLogin), new { provider = "Microsoft", returnUrl = returnUrl });
        //return View();
    }

这似乎可行,但如果有更好的方法,我将不胜感激任何反馈或建议。