MVC Owin 外部登录断开数据库
MVC Owin external login disconnect database
我有一个用于用户帐户和外部登录的基本 MVC 5 站点设置。
对于外部登录,我正在为员工使用本地 ADFS OpenID Connect,因此它应该类似于 Azure AD。
因此,在这种情况下,外部登录的 MVC Identity 2.0 措辞实际上是针对内部用户(员工)的。员工将使用 ADFS,public 将在 aspnet 数据库中拥有用户帐户。
MVC模板中的正常工作流程,将外部用户添加到aspnet数据库。工作流添加它们或检查用户是否在该数据库的适当表中。
我想为员工断开此数据库,因为他们已经通过 ADFS 的身份验证,因为我可以使用我们的 AD 授权他们并声称没有理由将他们添加到数据库中。
这是AccountController中的标准代码。
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
// Sign in the user with this external login provider if the user already has a login
//var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
case SignInStatus.Failure:
default:
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
此处的 loginInfo 显示用户已通过身份验证。
结果变量为假,因为用户不在 aspnet 数据库中,因此会将用户发送到 ExternalLoginConfirmation 视图。
如果我修改 switch 语句以将用户发送到 returnUrl,则该控制器操作上的 Authenticate 属性会将用户视为未通过身份验证并重新启动该过程,因为用户未根据内置工作流程进行身份验证。
如何拦截此工作流并满足授权属性?我检查了这些属性,它们 return 错误。
var authenticated = HttpContext.User.Identity.IsAuthenticated;
var authenticated2 = HttpContext.Request.IsAuthenticated;
var authenticated3 = HttpContext.GetOwinContext().Authentication;
通过删除检查数据库表的代码,我能够断开 aspnet 数据库与工作流的连接。
新代码退出外部 cookie,生成新的应用程序 cookie,并将声明从外部 cookie 复制到应用程序 cookie。
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
//We signed in with an external provider which creates and external cookie but this is not sufficient for application
//authorization so we need to create an application cookie and copy the existing claims and add new claims as needed
var externalClaims = loginInfo.ExternalIdentity.Claims;//get the current external claims for the user
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);//sign out of external authentication
var claims = externalClaims.ToList();//create a new list of the external claims
//add the identityprovider claim since this is needed for the AntiForgeryToken
claims.Add(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", loginInfo.DefaultUserName));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);//create new identity
AuthenticationManager.SignIn(identity);//sign in with the new local identity containing an application cookie
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return RedirectToLocal(returnUrl);
}
我有一个用于用户帐户和外部登录的基本 MVC 5 站点设置。 对于外部登录,我正在为员工使用本地 ADFS OpenID Connect,因此它应该类似于 Azure AD。 因此,在这种情况下,外部登录的 MVC Identity 2.0 措辞实际上是针对内部用户(员工)的。员工将使用 ADFS,public 将在 aspnet 数据库中拥有用户帐户。
MVC模板中的正常工作流程,将外部用户添加到aspnet数据库。工作流添加它们或检查用户是否在该数据库的适当表中。 我想为员工断开此数据库,因为他们已经通过 ADFS 的身份验证,因为我可以使用我们的 AD 授权他们并声称没有理由将他们添加到数据库中。
这是AccountController中的标准代码。
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
// Sign in the user with this external login provider if the user already has a login
//var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
case SignInStatus.Failure:
default:
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
此处的 loginInfo 显示用户已通过身份验证。
结果变量为假,因为用户不在 aspnet 数据库中,因此会将用户发送到 ExternalLoginConfirmation 视图。
如果我修改 switch 语句以将用户发送到 returnUrl,则该控制器操作上的 Authenticate 属性会将用户视为未通过身份验证并重新启动该过程,因为用户未根据内置工作流程进行身份验证。
如何拦截此工作流并满足授权属性?我检查了这些属性,它们 return 错误。
var authenticated = HttpContext.User.Identity.IsAuthenticated;
var authenticated2 = HttpContext.Request.IsAuthenticated;
var authenticated3 = HttpContext.GetOwinContext().Authentication;
通过删除检查数据库表的代码,我能够断开 aspnet 数据库与工作流的连接。
新代码退出外部 cookie,生成新的应用程序 cookie,并将声明从外部 cookie 复制到应用程序 cookie。
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
//We signed in with an external provider which creates and external cookie but this is not sufficient for application
//authorization so we need to create an application cookie and copy the existing claims and add new claims as needed
var externalClaims = loginInfo.ExternalIdentity.Claims;//get the current external claims for the user
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);//sign out of external authentication
var claims = externalClaims.ToList();//create a new list of the external claims
//add the identityprovider claim since this is needed for the AntiForgeryToken
claims.Add(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", loginInfo.DefaultUserName));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);//create new identity
AuthenticationManager.SignIn(identity);//sign in with the new local identity containing an application cookie
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return RedirectToLocal(returnUrl);
}