如何在Razor中执行Active Directory身份验证(cshtml)

时间:2014-07-16 14:40:58

标签: authentication razor active-directory ldap

我正在用Razor做一个简单的网站。目前,我有基于数据库的身份验证,如下所示:

在_AppStart.chtml中:

WebSecurity.InitializeDatabaseConnection("db_connection",
       "users", "id", "username", true);

在login.cshtml页面中:

    username = Request["username"];
    password = Request["password"];

    if (WebSecurity.Login(username, password, true))
    {
        Response.Redirect("/admin");
    }
    else
    {
        errorMessage = "Login was not successful.";
    }

在受保护的CSHTML页面中,我在页面顶部有以下内容:

if (!WebSecurity.IsAuthenticated)
{
    Response.Redirect("/login.cshtml");
}

一切都很简单,效果很好。现在我想用AD添加身份验证。我不知道该怎么做。

我来自Java世界,拥有多年的经验。对于这个简单的网站,我不需要MVC架构。我需要类似于上面的简单事情(如果可能的话)。我需要在login.cshtml文件中进行身份验证。我google了很多,无法找到我需要的教程(以便我可以复制和粘贴)。

非常感谢任何指示或帮助!

谢谢和问候

更新:此应用程序位于内部网络上。

更新2:以下是我成功实施X3074861X代码后的代码

if (IsPost)
{
    username = Request["username"];
    password = Request["password"];
    var domain = "domain";
    var host = "host";
    var port = "389";

    LdapConnection ldapConnection = new LdapConnection(host + ":" + port);
    try
    {
        // authenticate the username and password
        using (ldapConnection)
        {
            // pass in the network creds, and the domain.
            var networkCredential = new NetworkCredential(username, password, domain);
            // if we're using unsecured port 389, set to false. If using port 636, set this to true.
            ldapConnection.SessionOptions.SecureSocketLayer = false;
            // since this is an internal application, just accept the certificate either way
            ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
            // to force NTLM\Kerberos use AuthType.Negotiate, for non-TLS and unsecured, just use AuthType.Basic
            ldapConnection.AuthType = AuthType.Basic;
            // this is where the authentication occurs
            ldapConnection.Bind(networkCredential);

            //check local database to make sure the user is one of we allowed
            if (WebSecurity.Login(username, "fixed-password, just to check whether someone is on the list of allowed people", true))
            {
                Response.Redirect("/admin");
            }
            else
            {
                errorMessage = "Login was not successful.";
            }
        }
    }

    catch (LdapException exception)
    {
        //Authentication failed, exception will dictate why
        errorMessage = "Login was not successful.";
    }

一些解释。我无法控制AD,所以我只能对用户进行身份验证。我还有一个小的本地数据库,表明谁可以访问该应用程序。有权访问该应用的每个人都拥有相同的权利。

感谢和归功于X3074861X。

1 个答案:

答案 0 :(得分:3)

由于这是一个内部应用程序,并且您正在寻找简单的东西,我会考虑编写一个类来进行Active Directory身份验证。但是,为了实现这一点,你需要做几件事:

  • 对项目中System.DirectoryServices.Protocols的引用。
  • Active Directory服务器的IP或DNS名称。我们会在下面的代码中将其称为host
  • 它正在运行的端口(LDAPS将是端口636,基本LDAP将是端口389)。我们会在下面的代码中将其称为port
  • 您的用户所属的域。我们会在下面的代码中将其称为domain

现在您已经拥有了这个功能,您可以将其连接起来,以针对您的AD实例检查请求中的凭据。我会尝试这样的事情:

// the username and password to authenticate
username = Request["username"];
password = Request["password"];

// define your connection
LdapConnection ldapConnection = new LdapConnection("host:port");

try
{
      // authenticate the username and password
      using (ldapConnection)
      {
          // pass in the network creds, and the domain.
          var networkCredential = new NetworkCredential(username, password, domain);

          // if we're using unsecured port 389, set to false. If using port 636, set this to true.
          ldapConnection.SessionOptions.SecureSocketLayer = false;

          // since this is an internal application, just accept the certificate either way
          ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };

          // to force NTLM\Kerberos use AuthType.Negotiate, for non-TLS and unsecured, just use AuthType.Basic
          ldapConnection.AuthType = AuthType.Basic;

          // authenticate the user
          ldapConnection.Bind(networkCredential);
      }
      catch (LdapException ldapException)
      {
          //Authentication failed, exception will dictate why
      }
}

此外,与之前您传达授权问题的方式相同,ldapException可以告诉您呼叫失败的原因。如果要显示自定义消息传递,我会检查LdapException.ErrorCode属性,并根据error codes创建返回消息的case语句。

或者,您可以直接将LdapException.Message输出到页面 - 无论哪种方式,这至少会指示用户为什么他们的登录无法正常工作。