在过去的几个星期里,这个问题一直在乱问,但是现在我真的需要解决这个问题,我似乎无法理解它。
简而言之:我有一个启用了表单身份验证的nancy应用程序。所有工作都很好,期望会话在应用重启之间不会持续存在,所以看起来如此。这应该有效,因为表单身份验证默认使用cookie。你们有什么想法会导致这种行为吗?这是我的代码:
Bootstrapper.cs:
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
base.RequestStartup(container, pipelines, context);
var formsAuthConfiguration = new FormsAuthenticationConfiguration()
{
RedirectUrl = "~/user/login",
UserMapper = container.Resolve<IUserMapper>()
};
FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
}
并在应用启动中:
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
Nancy.Session.CookieBasedSessions.Enable(pipelines);
//Nancy.Session.MemoryCacheBasedSessions.Enable(pipelines); <-- disabled just to be sure
Nancy.Json.JsonSettings.RetainCasing = true;
Nancy.Json.JsonSettings.MaxJsonLength = Int32.MaxValue;
StaticConfiguration.DisableErrorTraces = false;
Elmahlogging.Enable(pipelines, "elmah");
//Some background job initialization...
}
处理登录/ POST请求的het模块中的路由:
Post["/login"] = parameters =>
{
VerifyUserViewModel userLoginData = this.Bind();
var verified = userManager.VerifyAccount(userLoginData.Email, userLoginData.Password);
userLoginData.LoginFailed = false;
if (verified == false)
{
userLoginData.LoginFailed = true;
return View["SignIn", userLoginData];
}
else
{
var user = userManager.GetByEmail((string)Request.Form.Email);
DateTime? expiry = null;
if (this.Request.Form.RememberMe.HasValue)
{
expiry = DateTime.Now.AddDays(30);
}
return this.LoginAndRedirect(user.Guid, expiry, "/dash");
}
};
最后,IUserMapper实现:
public class UserDatabase : IUserMapper
{
private readonly IUserManager _userManager;
public UserDatabase(IUserManager userManager)
{
_userManager = userManager;
}
public Nancy.Security.IUserIdentity GetUserFromIdentifier(Guid identifier, Nancy.NancyContext context)
{
var user = (ReflectUser)_userManager.GetByGuid(identifier);
var identity = new ReflectWebUser();
identity.Map(user);
return identity;
}
}
你们注意到我的代码有什么奇怪的东西会妨碍会话持久性吗?
请注意,我也在此应用中使用基于令牌的身份验证,但我已将其完全禁用以进行测试。此外,在实现令牌验证之前存在此问题。
谢谢!
答案 0 :(得分:6)
让链接死掉。
问题是Nancy在应用程序启动时生成加密密钥,这意味着当您在开发期间重建应用程序并重新请求页面时,cookie检查将失败并被删除,导致用户显示未经身份验证。
如果IIS被回收,应用程序将重新启动,生成新密钥,bam用户将被注销,也会发生同样的情况。
解决方案是自己生成一个特定的密钥。配置Forms Auth时,您可以创建自己的加密配置:
var cryptographyConfiguration = new CryptographyConfiguration(
new RijndaelEncryptionProvider(new PassphraseKeyGenerator("SuperSecretPass", new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 })),
new DefaultHmacProvider(new PassphraseKeyGenerator("UberSuperSecure", new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 })));
var config =
new FormsAuthenticationConfiguration()
{
CryptographyConfiguration = cryptographyConfiguration,
RedirectUrl = "/login",
UserMapper = container.Resolve<IUserMapper>(),
};
这将在开发和应用程序回收过程中持续登录。