【发布时间】: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