这是我刚刚努力奋斗的事情,我现在有了答案,所以我会问这个并回答这个问题。
问题是由于我在新的MVC 5站点上设置了身份验证,该站点与现有的非常自定义的成员资格数据库集成。
我基本上需要复制FormsAuthentication功能以让用户登录会话。除了普通的用户名/密码方法外,该系统还具有自动登录功能,该功能使用网址中的键/值。
我将控制器代码拆分如下:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var loginResult = _authenticationService.Login(model.Email, model.Password, returnUrl);
if (loginResult.Succeeded)
{
_loginFacade.DoLogin(loginResult, model.RememberMe);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
return View(model);
}
[AllowAnonymous]
public ActionResult Autologin(string key, string value)
{
if (ModelState.IsValid)
{
var loginResult = _authenticationService.AutoLogin(key, value);
if (loginResult.Succeeded)
{
_loginFacade.DoLogin(loginResult, false);
}
else
{
ModelState.AddModelError("", "error message goes here");
}
}
return View("Login");
}
对_authenticationService.Login的调用很好。那里没问题。
在对DoLogin的调用中,我正在做各种事情来创建身份验证属性,然后能够在新用户中签名,但无论我做什么,用户都不会在浏览器中登录:< / p>
public void DoLogin(LoginResult<Agent> loginResult, bool rememberMe)
{
string redirectUrl;
if (loginResult.Succeeded)
{
var claimsIdentity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, loginResult.User.Email),
new Claim(ClaimTypes.Role, "User"),
new Claim(ClaimTypes.NameIdentifier, loginResult.User.Id.ToString()),
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", loginResult.User.Id.ToString())
}, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);
var authProperties = new AuthenticationProperties
{
IsPersistent = rememberMe,
};
if (rememberMe)
{
authProperties.ExpiresUtc = DateTime.UtcNow.AddMonths(1);
}
authProperties.Dictionary.Add("Id", loginResult.User.Id.ToString());
var authentication = _context.GetOwinContext().Authentication;
authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
authentication.SignIn(authProperties, claimsIdentity);
DoStuff();
redirectUrl = GetRedirectUrl();
}
else
{
redirectUrl = GetOtherRedirectUrl();
}
_context.Response.Redirect(redirectUrl, true);
}
我会将解决方案作为答案发布
答案 0 :(得分:7)
当我跳过Response.Redirect行时,发生了答案的初步线索。代码在那种情况下起作用。
基本上,
_context.Response.Redirect(redirectUrl, true);
需要
_context.Response.Redirect(redirectUrl, false);
与FormsAuthentication(在编写身份验证代码时实际设置cookie)不同,AuthenticationManager会创建AuthenticationResponseGrant或AuthenticationResponseRevoke对象。
因此,在调用authentication.SignIn(authProperties,claimsIdentity)时,不会设置身份验证cookie。它们稍后被调用,因此使用Response.Redirect结束响应将在将cookie添加到响应对象之前终止该线程。通过将endResponse参数更改为false,cookie将按预期应用于响应对象。