代码之家  ›  专栏  ›  技术社区  ›  synergetic

Asp。默认Razor Pages应用程序中的Net Core 2.0 Azure Ad身份验证

  •  0
  • synergetic  · 技术社区  · 6 年前

    使用VS 2017默认模板创建的Web应用具有以下启动。ConfigureServices方法:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddAzureAd(options => Configuration.Bind("AzureAd", options))
        .AddCookie();
    
        services.AddMvc(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })
        .AddRazorPagesOptions(options =>
        {
            options.Conventions.AllowAnonymousToFolder("/Account");
        });
    }
    

    因此,Authorize filter是全局应用的,甚至对于索引主页也是如此(例外是/Account/AccessDenied和/Account/SignedOut页面,在上述代码中应用[允许匿名])。这意味着,当应用程序启动时,它会立即转到Microsoft登录页面,这对我来说很好。

    AccountController具有以下代码:

    [Route("[controller]/[action]")]
    public class AccountController : Controller
    {
        [HttpGet]
        public IActionResult SignIn()
        {
            var redirectUrl = Url.Page("/Index");
            return Challenge(
                new AuthenticationProperties { RedirectUri = redirectUrl },
                OpenIdConnectDefaults.AuthenticationScheme
            );
        }
    
        [HttpGet]
        public IActionResult SignOut()
        {
            var callbackUrl = Url.Page("/Account/SignedOut", pageHandler: null, values: null, protocol: Request.Scheme);
            return SignOut(
                new AuthenticationProperties { RedirectUri = callbackUrl },
                CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme
            );
        }
    }
    

    这里是AccountController。由于全局应用了授权筛选器,Signin将隐式应用[授权]。显然,除非用户首先注销并明确请求,否则代码不会运行 /account/signin 网址。但即使在这种情况下,首先要做的就是隐式[授权]过滤器,代码只有在用户成功登录后才能运行。所以,问题是,返回ChallengeResult有什么意义,因为用户应该已经在那一点上进行了身份验证?也许,只需重定向到如下索引页?

    [HttpGet]
    public IActionResult SignIn()
    {
        return RedirectToPage("/Index");
    }
    

    或者,像下面一样,为什么不将[AllowAnonymous]应用于AccountController。登录,以便在用户请求时立即运行 /帐户/登录 url?

    [HttpGet]
    [AllowAnonymous]
    public IActionResult SignIn()
    {
        var redirectUrl = Url.Page("/Index");
        return Challenge(
            new AuthenticationProperties { RedirectUri = redirectUrl },
            OpenIdConnectDefaults.AuthenticationScheme
        );
    }
    

    还有一个问题。我想在用户登录后立即执行一些代码。如果是AccountController,则将代码放在何处。除非明确请求,否则登录不会运行?默认模板创建了另一个类,称为AzureAdAuthenticationBuilderExtensions。我是否应该连接到该类中的OpenId事件并将代码放入这些事件处理程序中?

    1 回复  |  直到 6 年前
        1
  •  1
  •   juunas    6 年前

    用户将在注销后看到登录链接的一种情况。 从某种意义上说,重定向到索引页的效果与案例中的挑战相同。 你的 AccountController 应该有 [AllowAnonymous] 因为它在其他方面没有真正的意义。

    要在登录后执行某些操作,可以在OpenId连接处理程序上挂接各种事件。这个 OnTicketReceived 活动可能适合您。 您可以在上查看所有可用的事件 OpenIdConnectEvents 及其基类 RemoteAuthenticationEvents