Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 如何整合;“用户”;在我的DDD模型中使用身份验证用户?_Asp.net_Asp.net Mvc_Authentication_Domain Driven Design - Fatal编程技术网

Asp.net 如何整合;“用户”;在我的DDD模型中使用身份验证用户?

Asp.net 如何整合;“用户”;在我的DDD模型中使用身份验证用户?,asp.net,asp.net-mvc,authentication,domain-driven-design,Asp.net,Asp.net Mvc,Authentication,Domain Driven Design,我正在创建我的第一个ASP.NETMVC站点,并且一直在尝试遵循域驱动开发。“我的网站”是一个项目协作网站,用户可以被分配到网站上的一个或多个项目。然后将任务添加到项目中,并且可以将项目中具有的用户分配给任务。因此,“用户”是我的领域模型的一个基本概念 我的计划是拥有一个“用户”模型对象,它包含关于用户的所有信息,并且可以通过IUserRepository访问。每个用户都可以通过一个用户ID进行标识。虽然我现在不确定我是否希望UserId是字符串还是整数 我的域对象用户和IUserReposit

我正在创建我的第一个ASP.NETMVC站点,并且一直在尝试遵循域驱动开发。“我的网站”是一个项目协作网站,用户可以被分配到网站上的一个或多个项目。然后将任务添加到项目中,并且可以将项目中具有的用户分配给任务。因此,“用户”是我的领域模型的一个基本概念

我的计划是拥有一个“用户”模型对象,它包含关于用户的所有信息,并且可以通过IUserRepository访问。每个用户都可以通过一个用户ID进行标识。虽然我现在不确定我是否希望UserId是字符串还是整数

我的域对象用户和IUserRepository应该如何与我的站点的更多管理功能(如授权用户并允许他们登录)相关联?如何将域模型与ASP.NET的其他方面集成,如HttpContext.User、HttpContext.Profile、自定义成员资格提供程序、自定义ProfileProvider或自定义属性

我应该创建一个自定义的MembershipProvider和/或ProfileProvider来包装我的IUserRepository吗?尽管如此,我也可以预见为什么我可能希望将域模型中的用户信息与站点上的用户授权分开。例如,将来我可能希望从窗体身份验证切换到windows身份验证


最好不要尝试重新发明轮子,坚持ASP.NET中内置的标准SqlMembershipProvider?每个用户的配置文件信息将存储在域模型(用户/IUserRepository)中,但这不包括他们的密码。然后,我会使用标准的ASP.NET成员身份资料来处理创建和授权用户的问题?因此,在创建新用户的帐户或首次登录时,需要有一些代码知道如何在IUserRepository中为新用户创建配置文件。

是-这是一个很好的问题。就像“安德鲁·库珀”,我们的团队也经历了这一切

我们采用了以下方法(正确或错误):

自定义会员资格提供商

我和其他开发人员都不是内置ASP.NET成员资格提供程序的粉丝。对于我们的网站(简单的、由UGC驱动的社交网站)来说,它太臃肿了。我们创建了一个非常简单的应用程序,它只满足应用程序的需要。而内置的成员资格提供程序可以提供您可能需要的所有功能,但很可能不会

自定义表单身份验证单/身份验证

应用程序中的所有内容都使用接口驱动的依赖项注入(StructureMap)。这包括表单身份验证。我们创建了一个非常薄的界面:

public interface IAuthenticationService
{
   void SignIn(User user, HttpResponseBase httpResponseBase);
   void SignOut();
}
这个简单的界面允许简单的模拟/测试。在实现中,我们创建了一个自定义表单身份验证票证,其中包含:每个HTTP请求都需要用户ID和角色等内容,它们不会经常更改,因此不应该在每个请求中提取

然后,我们使用一个操作过滤器来解密表单身份验证票证(包括角色),并将其粘贴到
HttpContext.Current.User.Identity
(我们的主要对象也是基于接口的)

使用[Authorize]和[AdminOnly]

我们仍然可以使用MVC中的授权属性。我们还为每个角色创建了一个<代码>[AdminOnly]只需检查当前用户的角色,并抛出401(禁止)

简单,用户单表,简单POCO

所有用户信息都存储在一个表中(除了“可选”用户信息,如个人资料兴趣)。这被映射到一个简单的POCO(实体框架),它也在对象中内置了域逻辑

用户存储库/服务

特定于域的简单用户存储库。例如更改密码、更新配置文件、检索用户等。存储库调用我上面提到的用户对象上的域逻辑。该服务是存储库顶部的一个薄包装器,它将单个存储库方法(例如Find)分离为更专门的方法(FindById、FindByNickname)

与安全性分离的域

我们的“域”包含用户及其关联信息。这包括姓名、个人资料、facebook/社交整合等

“登录”、“注销”等处理的是身份验证,“User.IsInRole”等处理的是授权,因此不属于域

因此,我们的控制器同时使用
iaauthenticationservice
IUserService

创建概要文件是域逻辑的一个完美例子,它也与身份验证逻辑混合在一起

以下是我们的产品的外观:

[HttpPost]
[ActionName("Signup")]
public ActionResult Signup(SignupViewModel model)
{
    if (ModelState.IsValid)
    {
        try
        {
            // Map to Domain Model.
            var user = Mapper.Map<SignupViewModel, Core.Entities.Users.User>(model);

            // Create salt and hash password.           
            user.Password = _authenticationService.SaltAndHashPassword();

            // Signup User.
            _userService.Save(user);

            // Save Changes.
            _unitOfWork.Commit();

            // Forms Authenticate this user.
            _authenticationService.SignIn(user, Response);

            // Redirect to homepage.
            return RedirectToAction("Index", "Home", new { area = "" });
        }
        catch (Exception exception)
        {
            ModelState.AddModelError("SignupError", "Sorry, an error occured during Signup. Please try again later.");
            _loggingService.Error(exception);
        }
    }

    return View(model);
}
[HttpPost]
[行动名称(“注册”)]
公共行动结果注册(注册视图模型)
{
if(ModelState.IsValid)
{
尝试
{
//映射到域模型。
var user=Mapper.Map(模型);
//创建salt和hash密码。
user.Password=_authenticationService.SaltAndHashPassword();
//注册用户。
_userService.Save(用户);
//保存更改。
_unitOfWork.Commit();
//表单验证此用户的身份。
_authenticationService.SignIn(用户,响应);
//重定向到主页。
返回重定向到操作(“索引”,“主页”,新{area=”“});
}
捕获(异常)
{
AddModelError(“SignupError”,“抱歉,注册过程中出现错误。请稍后再试。”);
_loggingService.Error(异常);
}
}
返回视图(模型);
}
摘要

上述措施对我们很有效。我喜欢有一个简单的用户表,一个
if (built in stuff works fine) {
    use the built in stuff;  
} else {
    write your own;
}

if (easier to write your own then figure out how to use another tool) {
    write your own;
} else {
    use another tool;
}

if (need feature not in the system) {
    if (time to extend existing api < time to do it yourself) {
        extend api;
    } else {
        do it yourself;
    }
}