2011-07-11 83 views
5

我正在关注专业ASP.NET设计模式中的案例研究Scott Millet。在案例研究中,认证在基础设施项目中处理。它包含像AspFormsAuthentication这样的实现:IFormsAuthentication,AspMembershipAuthentication:ILocalAuthenticationService。DDD身份验证服务

这很好,因为他使用内置的成员资格提供程序,但是,我不是,所以我需要访问我的资料库。在我的场景中,将我的ILocalAuthenticationService和AspMembershipAuthentication实现放置在Services项目中不是更好吗?

我问这个别处,有人回答说:

我还是会放的功能拉凭据在基础设施层,因为这层垂直对齐到另一个水平层和所有层访问它。由于您没有使用ASP.NET成员资格提供程序,并且可能正在使用可能只使用加密凭据的自定义内容,因此仍然可以使用基础结构层来包装这些凭据的访问权限,并允许存储库在需要时使用它们。您可以让服务层获取并传递它们,但是您有太多的层了解数据将如何被检索/保留,以及需要什么授权访问,这在尝试分层和分离问题时是不好的。

太好了。这是有道理的。但我不知道该从哪里出发。从案例研究中的代码:

public class AspMembershipAuthentication : ILocalAuthenticationService 
{ 
    public User Login(string email, string password) 
    { 
     User user = new User(); 
     user.IsAuthenticated= false; 

     if (Membership.ValidateUser(email, password)) 
     { 
      MembershipUser validatedUser = Membership.GetUser(email); 
      user.AuthenticationToken = validatedUser.ProviderUserKey.ToString(); 
      user.Email = email; 
      user.IsAuthenticated = true; 
     } 

     return user; 
    } 

    public User RegisterUser(string email, string password) 
    {    
     MembershipCreateStatus status; 
     User user = new User(); 
     user.IsAuthenticated = false; 

     Membership.CreateUser(email, password, email, 
           Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 
           true, out status); 

     if (status == MembershipCreateStatus.Success) 
     { 
      MembershipUser newlyCreatedUser = Membership.GetUser(email); 
      user.AuthenticationToken = newlyCreatedUser.ProviderUserKey.ToString(); 
      user.Email = email; 
      user.IsAuthenticated = true; 
     } 
     else 
     { 
      switch (status) 
      { 
       case MembershipCreateStatus.DuplicateEmail: 
        throw new InvalidOperationException(
          "There is already a user with this email address."); 
       case MembershipCreateStatus.DuplicateUserName: 
        throw new InvalidOperationException(
          "There is already a user with this email address."); 
       case MembershipCreateStatus.InvalidEmail: 
        throw new InvalidOperationException(
          "Your email address is invalid"); 
       default: 
        throw new InvalidOperationException(
        "There was a problem creating your account. Please try again."); 
      } 
     } 

     return user; 
    }  
} 

如果我不使用成员资格提供,我如何连接到数据库来检查用户名和密码匹配,其他可能的检查项目之中?

+1

认证是应用程序级别的问题。它不是你的域名的一部分。 – jfar

回答

3

在您的基础架构层中创建一个实现ILocalAuthenticationService的类并进行所需的调用。

或者,如果ILocalAuthenticationService太ASP.NET-y(使用它的用户返回类型),您可能需要推出自己的ILocalAuthenticationService变体并实现该变体。

然后在您需要时使用您的IoC容器来解析ILocalAuthenticationService。

+0

感谢您的回复。我的基础设施层已经具有ILocalAuthenticationService,与上面类似,实现AspMembershipAuthentication。我上面发布的实现使用默认的成员资格提供程序,而我不打算使用它。因此,从基础架构层中,我将如何访问数据以执行像上述实现对会员供应商所做的那样的检查? – getoutofmylaboratory

+0

我明白了 - 所以您的基础架构层无法看到数据层?如果您的身份验证服务存在于可以看到数据库的地方会怎样 - 从IoC的角度来看,您的客户并不在乎它的来源。如果基础架构层无法看到数据库,并且您的授权是基于数据库的,那么它不能存在于基础架构层中,因为您已经想出了:) – n8wrl

+0

正是!最初,我打算在服务层做这件事。然而,我质疑这是因为“这不是案例研究中的做法”。所以我问了一下,但是由于问题分离(从我发布的报价中),建议将其保留在基础架构层中。我正在考虑将它放入服务层,以便我可以使用我的存储库来与数据库进行通信。你会基于此建议什么? – getoutofmylaboratory