我们开始设计一大堆新服务来创建(WCF,ADO.NET数据服务,可能在某些时候在云端),弹出的一个问题是使用的身份验证和授权方案 - 那里很多!
我们基本上需要能够在各种协议(HTTP,HTTPS,TCP)上识别用户(实际人员和“虚拟”应用程序/服务用户),并且我们需要为他们分配至少一堆角色/允许查看某些数据和/或执行某些操作。
我们绝对不能单独使用Windows群组成员资格 - 我们的服务有很多外部消费者,我们不希望在内部域中为每个人设置域帐户。
所以我认为主要有三种选择:
首先 - 你会推荐这三种中的哪一种?为什么?
其次 - 我有更多的选择吗?
感谢任何提示,指示,意见!
马克
PS:看到目前为止的答案,我很惊讶投票选择#3的人数。我本以为MS能够设计出可以处理所有这些要求的可重用的东西......答案 0 :(得分:19)
实际上,答案可能是1和3的组合。
如果默认选项不完整,您可以通过编写membership,role或profile提供程序来利用框架为您提供的大量工具和功能尽你所能。
我们在许多客户端站点上都做过这种情况 - 例如我们的一个客户将其大多数用户存储为Commerce Server用户,并使用Commerce Server配置文件系统,因此我们编写了一个成员资格和配置文件提供程序与这些数据存储区交谈 - 一个相当简单的练习。
由于需要对原始TCP进行身份验证,大多数人可能会选择3 - 这会引入超出标准 ASP.NET 成员资格提供程序的层。
MS制作的大部分内容都是“确定”或“足够好”,但总会有一些边缘情况,你想要做一些“不太标准”的事情,这意味着你最终会自己滚动。我想有一些超出“Basic Auth”或“Windows Auth”的东西,对于普通开发人员来说很容易理解,他们采取了“让我们为网络构建这个”的明智选择。
如果你看看你可以通过多种方式对WCF服务进行身份验证,你会看到我的意思 - 这些 旨在处理不同的传输机制,因此更加复杂
也就是说,默认角色和配置文件提供程序相当有限(角色:没有层次结构,因此您需要检查每个可能的角色,或者明确地将每个角色分配给用户;配置文件:所有存储在一个字段中的逗号分隔符号值 - 不容易找到所有已设置值集的用户。
答案 1 :(得分:6)
我们使用(3)。实际上,这有助于我们在集成风景中使帐户与
同步答案 2 :(得分:3)
在最近的一个项目中,我们扩展了ASP.NET成员资格提供程序(编写了一个自定义提供程序),目的是使用一些基于角色的控件来管理权限。既然项目已经足够成熟,我们发现控制措施不够灵活,无法满足我们的要求,并且在某种程度上我们对MS成员资格路径感到后悔。如果你有时间正确地构建它,那么滚动你自己的身份验证将是最好的选择。
听起来您的应用程序有点混合,因为您为内部和外部客户提供服务,但也许会考虑为您的外部客户集成OpenID。有一些很棒的ASP.NET OpenID控件真正使外部客户处理新帐户变得毫无疑问。这当然取决于您的申请是如何“公开”的。
答案 3 :(得分:1)
Ldap有人吗?它是免费的,跨平台的,易于使用和远程管理,与其他身份验证方案的桥梁,以及您知道存在的更多语言的绑定......
答案 4 :(得分:1)
2003年不是AZMan吗?
我会推荐1或3.就我个人而言,我总是选择3.我有很多功能,我不使用或不使用。
答案 5 :(得分:1)
我会远离AzMan。我们走了一段路,并不喜欢我们破坏的城区。我们总是做基于AD的登录,使用当前用户的SID链接到数据库中的用户,然后获取权限从那里。鉴于你的设置,这可能是不可能的(或实际的),但无论如何我都会远离AzMan。
答案 6 :(得分:1)
我不是ASP或.NET开发人员,但我的直觉说(3)。您真的不希望公共使用的Web应用程序对您的公司网络有任何访问权限,更不用说能够在AD附近的任何地方放置身份验证凭证。
答案 7 :(得分:1)
您似乎提供太多且可扩展性以坚持一种技术解决方案
解决方案3.
我将整个应用程序基于User类 您只需对其进行建模,以便为您提供所需的灵活性和可扩展性
类似的东西:
[ClassAttribute ( "Yordan Georgiev", "1.0.2", "20090302", "20090415" , false )]
public class User
{
#region DomainName
private string _DomainName;
public string DomainName
{
get { return _DomainName; }
set { _DomainName = value; }
} //eof property DomainName
#endregion DomainName
#region Status
private int _Status;
public int Status
{
get { return _Status; }
set { _Status = value; }
} //eof property Status
#endregion Status
#region Password
private string _Password = Resources.GV.Pass;
public string Password
{
get { return _Password; }
set {
_Password = GenApp.Utils.Security.Encryptor.Encrypt ( value,
GenApp.Conf.GenAppSettings.Instance.EncryptionAlgorithm );
//debug_Password = value; //unencrypted
}
} //eof property Password
#endregion Password
#region ListUserRoles
private List<UserRole> _ListUserRoles;
public List<UserRole> ListUserRoles { get { return _ListUserRoles; } set { _ListUserRoles = value; } }
#endregion ListUserRoles
#region UserSettings
private GenApp.Conf.UserSettings _UserSettings;
public GenApp.Conf.UserSettings UserSettings
{
get {
if (_UserSettings == null)
_UserSettings = (GenApp.Conf.UserSettings)GenApp.Conf.GenAppSettings.Instance;
return _UserSettings;
}
set { _UserSettings = value; }
} //eof property UserSettings
}