如何在Azure AD身份验证之后重定向到ASP中的其他控制器操作Net Core MVC
我已经设置了我的ASP Net Core 2.0项目以使用Azure AD进行身份验证(在使用OIDC的VS2017中使用标准Azure AD身份验证模板)。一切工作正常,应用程序返回到基地址(/)并在验证成功后运行HomeController.Index操作。如何在Azure AD身份验证之后重定向到ASP中的其他控制器操作Net Core MVC
但是我现在想在验证后重定向到不同的控制器操作(AccountController.CheckSignIn),以便我可以检查用户是否已经存在于我的本地数据库表中,如果不存在(即它是新用户)用户记录,然后重定向到HomeController.Index操作。
我可以把这个检查放在HomeController.Index操作本身,但我想避免每次用户单击主页按钮时运行此检查。
这里有一些代码片段可能有助于让清晰......在appsettings.json
AAD设置
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<my-domain>.onmicrosoft.com",
"TenantId": "<my-tennant-id>",
"ClientId": "<my-client-id>",
"CallbackPath": "/signin-oidc" // I don't know where this goes but it doesn't exist anywhere in my app and authentication fails if i change it
}
我添加了一个新的动作,我AccountController.CheckSignIn来处理这一要求,但我在认证后找不到方法来调用它。
public class AccountController : Controller
{
// I want to call this action after authentication is successful
// GET: /Account/CheckSignIn
[HttpGet]
public IActionResult CheckSignIn()
{
var provider = OpenIdConnectDefaults.AuthenticationScheme;
var key = User.FindFirstValue(ClaimTypes.NameIdentifier);
var info = new ExternalLoginInfo(User, provider, key, User.Identity.Name);
if (info == null)
{
return BadRequest("Something went wrong");
}
var user = new ApplicationUser { UserName = User.Identity.Name };
var result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
result = await _userManager.AddLoginAsync(user, info);
if (!result.Succeeded)
{
return BadRequest("Something else went wrong");
}
}
return RedirectToAction(nameof(HomeController.Index), "Home");
}
// This action only gets called when user clicks on Sign In link but not when user first navigates to site
// GET: /Account/SignIn
[HttpGet]
public IActionResult SignIn()
{
return Challenge(
new AuthenticationProperties { RedirectUri = "/Account/CheckSignIn" }, OpenIdConnectDefaults.AuthenticationScheme);
}
}
我已经找到一种方法,使之通过使用重定向如下工作...
内启动
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Account}/{action=SignIn}/{id?}");
});
里面的AccountController
// GET: /Account/CheckSignIn
[HttpGet]
[Authorize]
public IActionResult CheckSignIn()
{
//add code here to check if AzureAD identity exists in user table in local database
//if not then insert new user record into local user table
return RedirectToAction(nameof(HomeController.Index), "Home");
}
//
// GET: /Account/SignIn
[HttpGet]
public IActionResult SignIn()
{
return Challenge(
new AuthenticationProperties { RedirectUri = "/Account/CheckSignIn" }, OpenIdConnectDefaults.AuthenticationScheme);
}
内AzureAdServiceCollectionExtensions(.NET核心2.0)
private static Task RedirectToIdentityProvider(RedirectContext context)
{
if (context.Request.Path != new PathString("/"))
{
context.Properties.RedirectUri = new PathString("/Account/CheckSignIn");
}
return Task.FromResult(0);
}
默认行为是:用户将被重定向到原始页面。例如,用户未通过身份验证并访问索引页面,经过身份验证后,他将被重定向到索引页面;用户未通过身份验证并访问联系页面,经过身份验证后,他将被重定向到联系人页面。
作为一种变通方法,您可以修改默认网站路线用户重定向到特定的控制器/动作:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Account}/{action=CheckSignIn}/{id?}"
);
});
您的定制逻辑后,您可以重定向用户到你的真正的默认页面(首页/索引) 。
我喜欢这种方法,因为它的简单性,但如果用户加载一个特定的页面(即家庭/联系人)会怎么样。我如何确保直接加载Home/Contact页面时首先调用Account/CheckSignIn动作? – OjM
您是否使用[授权]属性来保护您的控制器或操作?如果您使用该功能,则应将其重定向到azure广告登录页面,经过身份验证后,他将被重定向到Account/CheckSignIn。 –
是的,我正在使用[授权]属性。问题是,如果我已经显示了默认路由设置,那么这种方法只适用于我加载默认网站(即mysite.com)。但是,如果我输入url mysite.com/Home/关于默认路由被绕过并且帐户/签名签名从不被调用。有没有办法解决? – OjM
似乎你主张为正确的工作使用正确的工具,我喜欢它。 – JasonInVegas