我知道这是一个超级新手的问题,但我很难理解这一点。我正在我的n层应用程序中实现WebSecurity。我已将所有WebSecurity代码放在我的存储库层(最接近数据库层)中。
我有这样的代码:
public bool LogIn(string userName, string password, bool rememberMe)
{
return WebSecurity.Login(userName, password, rememberMe);
}
public void LogOut()
{
WebSecurity.Logout();
}
WebSecurity不需要知道登录的上下文 - 我传递参数。但退出呢?有10个用户注销,这里的代码如何知道要注销的用户?用户的上下文是否会以某种方式被推送到存储库层,从浏览器客户端到我的API控制器,再到我的服务层?
答案 0 :(得分:3)
我会创建服务类来实现此功能。此服务层方法应注入IPrincipal
和IUserRepository
。 IPrincipal
接口存储有关当前用户的信息。 HttpContext.Current.User
实现它。
public interface IAuthenticationService
{
bool SignIn(string userName, string password, bool rememberMe);
void SignOut();
}
public class WebSecurityAuthenticationService : IAuthenticationService
{
public WebSecurityAuthenticationService(IPrincipal user, IUserRepository userRepository)
{
}
....implementation...
}
您应该使用IOC容器来定义IPrincial
和HttpContext.Current.User
之间以及IUserRepository
与其基于数据库的实现之间的绑定。我推荐Ninject,但选择权在你手中。
答案 1 :(得分:2)
您的存储库层不应该知道哪个用户已登录。您的存储库层甚至不应该知道是用户。您的所有身份验证都应该由您的Web应用程序处理 - 您的Web应用程序然后通过对用户进行身份验证,访问您的存储库层,该层只执行任何告知的操作,并且不关心身份验证。
更新:正如John Saunders所指出的,这不会将您的Web应用程序绑定到成员资格数据库/表,而是绑定到您正在使用的成员资格系统。如果即使这对你来说过于紧密耦合,你也可以考虑定义一个IMembershipService
接口,将其传递给控制器的构造函数(可能通过依赖注入)。然后,您将创建IMembershipService
的具体实现,通过Login
实现Logout
和WebSecurity
。
这样,如果您决定以完全不同的方式实现成员身份,那么您唯一的限制就是您的替换成员资格服务必须实现IMembershipService
- 您可以完全更改技术和数据结构以及您的Web应用程序没有比这更聪明了。