简体   繁体   English

使用Windows身份验证定义AD服务器

[英]Using Windows Authentication, define AD-Server

We are developing a web-app which allows us to edit data from databases. 我们正在开发一个网络应用程序,使我们可以编辑数据库中的数据。 Because this app should be reachable from outside, we decided to put it on one of our DMZ-servers. 由于应该可以从外部访问此应用程序,因此我们决定将其放在我们的DMZ服务器之一上。 To have a centralized control over all user accessing this service, we decided to use Windows Authentication. 为了对所有访问此服务的用户进行集中控制,我们决定使用Windows身份验证。 But since the DMZ-servers are not members of the Active Directory in our local LAN, this does not work yet (getting "401 - Unauthorized: Access is denied due to invalid credentials."). 但是,由于DMZ服务器不是我们本地LAN中Active Directory的成员,所以这还行不通(获取“ 401-未经授权:访问由于凭据无效而被拒绝。”)。

I tried to specify the LDAP-ConnectionString like described here ASP.NET MVC: How to setup web.config for LDAP authentication? 我试图指定LDAP-ConnectionString,如此处所述ASP.NET MVC:如何为LDAP身份验证设置web.config? . But it does not work. 但这行不通。 I guess, this config was not designed to work with Windows Authentication ( <authentication mode="Windows"/> ). 我猜想,此配置并非设计用于Windows身份验证( <authentication mode="Windows"/> )。 Even if I test it on the local machine and put in wrong credentials, it authenticates me. 即使我在本地计算机上对其进行了测试并输入了错误的凭据,它也会对我进行身份验证。 So my guess is, that this config is getting entirely ignored. 所以我的猜测是,该配置已被完全忽略。

<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>

To be sure that the problem doesn't lie on the LDAP-Communication I made a LDAP-Query-Test. 为确保问题不在于LDAP通信,我进行了LDAP-Query-Test。 The DMZ-server is actually able to send LDAP-queries. DMZ服务器实际上能够发送LDAP查询。 I tested following and got positive results (and negative results by providing a wrong password) 我测试了以下内容,并获得了肯定的结果(通过提供错误的密码获得了否定的结果)

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"]);
}

Question: 题:

What I am looking for is like a config or a "custom-security-provider" where I can specify the LDAP-Server and use all inbuilt features of Windows Authentication. 我正在寻找的是一个配置或一个“ custom-security-provider”,可以在其中指定LDAP服务器并使用Windows身份验证的所有内置功能。 Is this possible? 这可能吗? How would I do this? 我该怎么做?

Disclaimer 免责声明

This may not help everyone and is probably not the cleanest method, but it helped me. 这可能对所有人没有帮助,可能不是最干净的方法,但这对我有所帮助。

To explain why I choose this method, here are the circumstances: 为了解释为什么我选择这种方法,在以下情况下:

  • Basically we just want to check if a given user has the right to access certain elements, by checking his group-membership (by using [Authorize] and User.IsInRole ). 基本上,我们只想通过检查某个组的成员身份(使用[Authorize]User.IsInRole )来检查给定用户是否有权访问某些元素。 And we want to manage all users on one place (AD) 而且我们要在一个地方(AD)管理所有用户

  • We have a limited timeframe, which does not allow us to invest too much time to find the best way. 我们的时限很短,这不允许我们花费太多时间来寻找最佳方法。

  • We already know what AD-Server we will be using and how we treat the users that will have access to the said service. 我们已经知道我们将使用什么AD服务器以及如何对待将有权访问上述服务的用户。 Also, users can't register by them selfs, so overall we have the control over, who has access to our ressources. 此外,用户无法自行注册,因此总体上我们可以控制谁有权访问我们的资源。

  • We want to keep the amount of running services as low as possible and since ADFS would be an additional service for us, we searched for alternatives. 我们希望将运行服务的数量保持在尽可能低的水平,并且由于ADFS对我们来说是一项额外的服务,因此我们在寻找替代方案。

  • Since the "Security-Management" is leaned on the FormsAuthentication (Cookie encryption) we believe it to be secure. 由于“安全管理”依赖于FormsAuthentication(Cookie加密),因此我们认为它是安全的。 Also we created a service-user with limited permissions to just read the LDAP. 另外,我们创建了一个服务用户,该用户仅具有读取LDAP的权限。

If you have security concerns, better solutions or just suggestions, feel free to add comments/answers. 如果您有安全问题,更好的解决方案或仅是建议,请随时添加评论/答案。

Quick Overview 快速概述

I ended up, creating a custom "SecurityProvider". 我最终创建了一个自定义“ SecurityProvider”。 I got inspired by https://support.microsoft.com/en-us/help/316748/how-to-authenticate-against-the-active-directory-by-using-forms-authen which describes the Authentication using FormsAuthentication and .aspx. 我受到https://support.microsoft.com/zh-CN/help/316748/how-to-authenticate-against-the-active-directory-by-using-forms-authen的启发,该文档描述了使用FormsAuthentication和.aspx。

Basically it sets the User ( HttpContext.User ) in the Application_AuthenticateRequest -Method in Global.asax. 基本上,它在Global.asax的Application_AuthenticateRequest -Method中设置用户( HttpContext.User )。 This is done by using a decrypted Cookie, which is set in the login with the help of PrincipalContext and FormsAuthentication . 这是通过使用解密的Cookie来完成的,该Cookie在PrincipalContextFormsAuthentication的帮助下在登录中设置。

CustomPrincipal 海关负责人

Since UserPrincipal does not implement IPrincipal , I made a wrapper called CustomPrincipal which implements IPrincipal and has a UserPrincipal as Property. 由于UserPrincipal不实现IPrincipal ,因此我制作了一个名为CustomPrincipal的包装,该包装实现了IPrincipal并将UserPrincipal作为属性。 This way I can retrieve a UserPrincipal -object from PrincipalContext and use it as User ( HttpContext.User ). 这样,我可以从PrincipalContext检索UserPrincipal ,并将其用作User( HttpContext.User )。

Application_AuthenticateRequest Application_AuthenticateRequest

Here I checked if the user is logged in by checking the cookie, and if he is, decrypt the cookie to get the username, create the needed CustomPrincipal -object and setting it as the User. 在这里,我通过检查cookie来检查用户是否登录,如果是,则解密cookie以获取用户名,创建所需的CustomPrincipal -object并将其设置为User。

Login 登录

On Login it takes the given username and password and uses the PrincipalContext to check if the given credentials are valid ( PrincipalContext.ValidateCredentials(username, password) ). 在登录时,它将使用给定的用户名和密码,并使用PrincipalContext来检查给定的凭据是否有效( PrincipalContext.ValidateCredentials(username, password) )。 If they are, a encrypted cookie containing the username gets generated. 如果是,则生成包含用户名的加密cookie。

Logout 登出

Logout just lets the "Auth"-Cookie expire. 注销仅使“ Auth” -Cookie过期。 Simple as that... 就那么简单...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM