我们正在开发一个web应用程序,它允许我们从数据库中编辑数据。因为这个应用程序应该可以从外部访问,所以我们决定把它放在我们的DMZ服务器上。为了对访问此服务的所有用户进行集中控制,我们决定使用Windows身份验证。但是,由于DMZ-服务器不是本地LAN中Active Directory的成员,这还不能工作(获得"401 -未经授权:访问由于凭据无效而被拒绝“)。
我尝试指定LDAP-ConnectionString,如这里所描述的,ASP.NET MVC: How to setup web.config for LDAP authentication?。但不起作用。我想,这个配置不是设计用来处理Windows (<authentication mode="Windows"/>)的。即使我在本地机器上测试它并输入错误的凭据,它也会验证我的身份。所以我的猜测是,这个配置被完全忽略了。
<connectionStrings>
<add name="ADConnectionString" connectionString="LDAP://<IP of AD-Server>/DC=<DomainName>"/>
</connectionStrings>
<system.web>
[...]
<authentication mode="Windows"/>
<authorization>
<deny users="?" />
</authorization>
<membership defaultProvider="ADMembershipProvider" >
<providers>
<clear/>
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider"
connectionStringName="ADConnectionString"
connectionUsername="<Domain>\<LDAP-Reader-User>"
connectionPassword="<LDAP-Reader-Password>"/>
</providers>
</membership>为了确保问题不在于LDAP通信,我做了一个LDAP查询测试。DMZ-服务器实际上能够发送LDAP查询。我测试了下面的结果,并得到了阳性结果(并通过提供错误的密码获得了阴性结果)
public bool TestPrincipalContext()
{
PrincipalContext c = new PrincipalContext(ContextType.Domain, "<IP of AD-Server>", "<LDAP-Reader-User>", "<LDAP-Reader-Password>");
return c.ValidateCredentials(Request.Form["username"], Request.Form["password"]);
}问题:
我正在寻找的是一个配置或“自定义安全提供程序”,我可以指定LDAP服务器并使用Windows身份验证的所有内置功能。这个是可能的吗?我该怎么做?
发布于 2018-03-26 10:31:15
免责声明
这可能不会对每个人都有帮助,也可能不是最干净的方法,但它帮助了我。
为了解释我为什么选择这种方法,请看下面的情况:
[Authorize]和User.IsInRole__)来检查给定的用户是否有权访问特定的元素。我们希望在一个地方管理所有的用户(AD)。如果您有安全问题、更好的解决方案或只是建议,请随意添加评论/答案。
快速概述
最后,我创建了一个定制的"SecurityProvider“。我受到了https://support.microsoft.com/en-us/help/316748/how-to-authenticate-against-the-active-directory-by-using-forms-authen的启发,它用FormsAuthentication和.aspx描述了身份验证。
基本上,它在HttpContext.User中设置Application_AuthenticateRequest-Method中的用户( Global.asax )。这是通过使用解密Cookie来完成的,它是在PrincipalContext和FormsAuthentication的帮助下在登录中设置的。
CustomPrincipal
由于UserPrincipal没有实现IPrincipal,所以我制作了一个名为CustomPrincipal的包装器,它实现了IPrincipal,并将UserPrincipal作为属性。通过这种方式,我可以从UserPrincipal-object检索PrincipalContext,并将其作为用户(HttpContext.User)使用。
Application_AuthenticateRequest
在这里,我通过签入cookie来检查用户是否登录,如果是,则解密cookie以获取用户名,创建所需的CustomPrincipal-object并将其设置为用户。
登录
在登录时,它使用给定的用户名和密码,并使用PrincipalContext检查给定的凭据是否有效(PrincipalContext.ValidateCredentials(username, password))。如果是,则生成包含用户名的加密cookie。
注销
注销只允许"Auth"-Cookie过期。这么简单..。
https://stackoverflow.com/questions/49446867
复制相似问题