【问题标题】:How to get Windows username in ASP.NET?如何在 ASP.NET 中获取 Windows 用户名?
【发布时间】:2019-04-12 22:59:22
【问题描述】:

对此相当陌生,但我一直在尝试创建一个 ASP.NET 网站来存档文件。我想捕获 Windows 用户名,因此当用户插入文件时,会记录插入文件的人。我有一张将使用该网站的用户表,为用户名提供记录参考。当我在开发环境中进行测试时,一切正常,我可以看到创建的记录。但是,在服务器上没有创建记录,我将其返回给我:

'The INSERT statement conflicted with the FOREIGN KEY constraint 
"FK_Person_BoxArchive_LastUpdate". The conflict occurred in database 
"BoxManagement", table "dbo.Person", column 'PersonID'.###-1###'

我尝试在 IIS 中启用 Windows 身份验证并尝试使用这些:

string userName = HttpContext.Current.User.Identity.Name.Replace(".", " ");
WindowsIdentity identity = HttpContext.Current.Request.LogonUserIdentity;

我用来将用户名传递给存储过程的代码是:

string userName = Environment.UserName.Replace(".", " ");
int userID = -1;
DataTable database = new DataTable();
using (SqlConnection con = new SqlConnection(dbString))
using (SqlCommand cmd = new SqlCommand("GetUserID", con))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@userName", Environment.UserName);
    con.Open();

    using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
        rdr.Read();
        userID = rdr.GetInt32(rdr.GetOrdinal("PersonID"));
        rdr.Close();
    }
}

而存储过程只是

SELECT PersonID FROM Person WHERE WindowsName = @userName

不确定我是否在寻找正确的地方,但希望这足以指向正确的方向。

编辑:

这是我用来插入文件的代码:

DataTable database = new DataTable();
string dbString = ConfigurationManager.ConnectionStrings["connArchiveDatabase"].ConnectionString;
using (SqlConnection con = new SqlConnection(dbString))
using (SqlCommand cmd = new SqlCommand("dbo.InsertAccountFile", con))
{
    try
    {
        int FileType = Int32.Parse(ddlInAccFileType.SelectedValue);
        string policyNumber = "";
        DateTime closedPolicy = new DateTime(1900, 01, 01);

        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.AddWithValue("@boxID", ddlInAccBox.Text);
        cmd.Parameters.AddWithValue("@policyNumber", policyNumber);
        cmd.Parameters.AddWithValue("@fileReference", tbInAccReference.Text);
        cmd.Parameters.AddWithValue("@archivedbyID", userID);
        cmd.Parameters.AddWithValue("@dateArchived", archivedDate);
        cmd.Parameters.AddWithValue("@closedPolicy", closedPolicy);
        cmd.Parameters.AddWithValue("@closedFile", tbInAccClosedDate.Text);
        cmd.Parameters.AddWithValue("@filetypeID", FileType);
        cmd.Parameters.AddWithValue("@comment", tbInAccComment.Text);
        cmd.Parameters.AddWithValue("@expectedDestruction", destructionDate);
        cmd.Parameters.AddWithValue("@lastupdateID", userID);
        cmd.Parameters.AddWithValue("@updatedDate", updateDate);

        SqlParameter archiveParameter = new SqlParameter
        {
            ParameterName = "@boxArchiveID",
            SqlDbType = SqlDbType.Int,
            Direction = ParameterDirection.Output
        };

        SqlParameter messageParameter = new SqlParameter
        {
            ParameterName = "@returnMessage",
            SqlDbType = SqlDbType.VarChar,
            Size = 255,
            Direction = ParameterDirection.Output
        };

        cmd.Parameters.Add(archiveParameter);
        cmd.Parameters.Add(messageParameter);

        con.Open();
        cmd.ExecuteNonQuery();

        string returnMessage = messageParameter.Value.ToString();

        ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('" + returnMessage + "###" + archiveParameter.Value.ToString() + "###" + "')", true);
        }

        catch (Exception ex)
        {
            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('" + ex.Message.ToString() + "')", true);
            return;
        }

        finally
        {
            con.Close();                    
        }                
}
ALTER PROCEDURE [dbo].[InsertAccountFile] 
    @boxID INT,
    @policyNumber VARCHAR(255),
    @fileReference VARCHAR(255),
    @archivedbyID INT,
    @dateArchived SMALLDATETIME,
    @closedPolicy SMALLDATETIME,
    @closedFile SMALLDATETIME,
    @filetypeID INT,
    @comment VARCHAR(255),
    @expectedDestruction SMALLDATETIME,
    @lastupdateID INT,
    @updatedDate SMALLDATETIME,     
    @boxArchiveID INT OUTPUT,
    @returnMessage VARCHAR(255) OUTPUT
AS
BEGIN
    SET NOCOUNT ON

    IF NOT EXISTS(SELECT * FROM BoxArchive WHERE BoxID = @boxID AND FileReference = @fileReference)

    BEGIN
        BEGIN TRY
            INSERT INTO BoxArchive (PolicyNumber, FileReference, ArchivedByID, DateArchived, DatePolicyClosed, ClosedFileDate, BoxID, FileTypeID, Comment, ExpectedDestructionDate, 
                                LastUpdateID, LastUpdateDate) 
            VALUES (@policyNumber, @fileReference, @archivedbyID, @dateArchived, @closedPolicy, @closedFile, @boxID, @filetypeID, @comment, @expectedDestruction,
                                @lastupdateID, @updatedDate)

            SET @returnMessage = 'Success.'
            SET @boxArchiveID = IDENT_CURRENT('BoxArchive') 
        END TRY

        BEGIN CATCH
            SET @returnMessage = ERROR_MESSAGE()
            SET @boxArchiveID = -1
        END CATCH
    END

    ELSE

    BEGIN
        SET @returnMessage = 'Error: "' + @fileReference + '" already exists in this box.' 
        SET @boxArchiveID = -1
    END

userName 在调试中正确返回了我的名字,userID 也知道我的 ID,在这种情况下为 8。在服务器上它似乎返回 -1。

【问题讨论】:

  • 你得到的错误是在插入语句上。但是,您是说该过程只有一个 select 语句。你确定你没有在任何地方使用插入?
  • 我有一个插入按钮,现在将编辑代码
  • 您试图从中获取价值的用户似乎在数据库中不存在,因为消息显示值 '-1' ..column 'PersonID'.###- 1###'... 不存在。在服务器中,您需要确保运行 .NET 进程的用户是正确的,因为您的进程可能在 IIS 中与另一个用户一起运行。是的,如上所述,您的错误在插入语句中,很高兴知道您如何将此数据插入到数据库中。
  • 添加了我的插入代码。我无法理解为什么它知道是我在本地插入文件,但在服务器上却没有。
  • I have tried enabling Windows Authentication in IIS - 您是否也禁用了匿名身份验证?

标签: c# sql asp.net iis


【解决方案1】:

好的,经过数小时的搜索,我设法找到了适合我的解决方案。在<system.web>下的web.config,我已经有了这个代码:

<authentication mode="Windows" />
<authorization>
  <allow users="*" />
</authorization>

我似乎缺少的一点是:

<identity impersonate ="true"/>

希望这可以帮助任何发现自己处于这种情况的人!

链接到@gokul 答案以获取更多详细信息here

【讨论】:

    【解决方案2】:

    因此,问题似乎在于在您的服务器中设置 Windows 身份验证。检查

    1. 在 IIS 中启用身份验证
    2. 身份验证模式的 web.config 文件 = 'windows' 行

    并查看https://docs.kentico.com/k10/managing-users/user-registration-and-authentication/configuring-windows-ad-authentication 以设置 AD 身份验证。

    希望对你有帮助:)

    【讨论】:

      【解决方案3】:

      你的代码中有些东西看起来很奇怪

      你说你得到的用户名是这样的:

      string userName = Environment.UserName.Replace(".", " ");
      

      但在下面,您将使用 Environment.UserName 直接传递其值 像这样:

      cmd.Parameters.AddWithValue("@userName", Environment.UserName);
      

      这真的是你的意思吗?此外,我强烈建议您记录您在服务器中获取的用户ID,这将使您的生活更轻松,您可以使用Nlog

      【讨论】:

      • 对不起,你是对的。虽然,Environment.UserName 是我需要通过的。我现在去看看,谢谢!
      猜你喜欢
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 2013-11-09
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      相关资源
      最近更新 更多