使用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事件并将代码放入这些事件处理程序中?