【问题标题】:Asp.Net Core 2.0 Azure Ad authentication in default Razor Pages app默认 Razor Pages 应用程序中的 Asp.Net Core 2.0 Azure Ad 身份验证
【发布时间】:2018-10-23 00:53:41
【问题描述】:

使用 VS 2017 默认模板创建的 Web 应用具有以下 Startup.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");
    });
}

因此,授权过滤器是全局应用的,即使是索引主页(例外是 /Account/AccessDenied 和 /Account/SignedOut 页面,它们在上面的代码中应用 [AllowAnonymous])。这意味着,当应用程序启动时,它会立即转到 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 将隐式应用 [Authorize],因为 Authorize 过滤器在全局范围内应用。显然,代码不会运行,除非用户先退出并明确请求/account/signin url。但是即使在那种情况下,首先发生的事情是隐式 [Authorize] 过滤器,并且代码只有在用户成功登录后才会运行。所以,问题是,返回 ChallengeResult 有什么意义,因为用户应该已经在那个时候被认证了吗?也许,只需重定向到下面的索引页面?

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

或者,如下所示,为什么不将 [AllowAnonymous] 应用于 AccountController.SignIn,以便在用户请求 /account/signin url 时立即运行?

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

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

【问题讨论】:

    标签: c# asp.net-core azure-active-directory asp.net-core-2.0 openid-connect


    【解决方案1】:

    用户在退出后会看到登录链接的一种情况。 从某种意义上说,重定向到索引页面与您的案例中的挑战具有相同的效果。 你的AccountController 应该有[AllowAnonymous],否则它没有任何意义。

    要在登录后执行某些操作,您可以在 OpenId Connect 处理程序上挂钩各种事件。 OnTicketReceived 事件可能对您有用。 您可以在OpenIdConnectEvents 及其基类RemoteAuthenticationEvents 上查看所有可用的事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-15
      • 2019-12-13
      • 2022-10-25
      • 2018-03-12
      • 2020-07-27
      • 1970-01-01
      • 2020-05-27
      • 1970-01-01
      相关资源
      最近更新 更多