【发布时间】:2023-03-21 17:05:01
【问题描述】:
我正在尝试实现一个非常简单的 FormsAuthentication 示例。这不是现实生活,但它引发了一个问题。旨在成为应用程序级别单例的 AuthenticationService 似乎被实例化了两次。
代码如下:
public class User : IUserIdentity
{
public string UserName { get; set; }
public IEnumerable<string> Claims { get; set; }
}
public interface IAuthenticationService
{
Guid GetIdentifier(string username, string password);
}
public class AuthenticationService : IUserMapper, IAuthenticationService
{
public readonly Guid Identifier = Guid.NewGuid();
private readonly string Username = "admin";
private readonly string Password = "x";
public Guid GetIdentifier(string username, string password)
{
return (username == Username && password == Password) ? Identifier : Guid.Empty;
}
public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
{
return (identifier == Identifier) ? new User { UserName = "admin" } : null;
}
}
public class MyBootstrapper : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
base.ConfigureApplicationContainer(container);
container.Register<IAuthenticationService, AuthenticationService>().AsSingleton();
}
}
上面的代码被我的LoginModule 使用如下。请注意,我正在通过模块的构造函数注入 AuthenticationService 的应用程序级单例实例。
public LoginModule(IAuthenticationService authenticationService)
{
Post["/login"] = _ =>
{
var identifier = authenticationService.GetIdentifier(
(string) Form.Username,
(string) Form.Password);
if (identifier.IsEmpty())
{
return Context.GetRedirect("~/login?error=true");
}
return this.LoginAndRedirect(identifier);
};
}
应该发生的是当用户POSTs他们的用户名和密码时,这些是由AuthenticationService通过GetIdentifier(..)方法检查的。如果凭据匹配,则返回单个 GUID 标识符。这个GUID 将始终相同,因为它是作为readonly 字段创建的,因此在应用程序启动时首次实例化单例AuthenticationService 时设置一次。
然而事实并非如此。而是创建了两个不同的 AuthenticationService 实例,一个注入到 LoginModule 构造函数中并用于调用 GetIdentifier(..) 方法,另一个实例用于 Nancy 调用 IUserIdentity.GetUserFromIdentifier(..) 方法。
这两个实例有不同的GUID 标识符,因此GetUserFromIdentifier(..) 方法总是返回null。
我测试了一个没有实现IUserMapper 的标准单例服务,它按预期工作,只创建了一个实例。
因此,Nancy 似乎两次实例化 IUserMapper 单例,一次在 FormsAuthentication 期间供其内部使用,一次注入我的 LoginModule 构造函数!
你能看出我的错误吗?
谢谢
【问题讨论】:
标签: singleton forms-authentication nancy