我有一个使用Windows身份验证的.net / c#Web应用程序(Web API)。该服务托管在我的本地计算机IIS 10上。应用程序池标识设置为我,当前登录Windows用户。计算机在活动目录域中。
我想使用当前登录到应用程序的帐户访问共享文件。文件具有适当的权限。为此,我使用如下模拟:
awk '/FAIL/ { match($0,/ Cause: /); n=RSTART+RLENGTH;
match(substr($0,n)," "); a[substr($0, n,RSTART-1)]++}
END{for(i in a) print i, a[i]}'
我使用当前Windows帐户登录,与应用程序池标识中设置的相同。与托管应用程序的本地计算机上的共享文件配合使用时效果很好。但是不适用于另一台计算机上的远程共享文件。另一台计算机也在活动目录域中。
在托管计算机上,我可以使用Windows资源管理器或浏览器访问共享文件。另外,如果我没有模拟用户,.net尝试使用应用程序池标识帐户(设置为同一用户,我)访问共享文件,并且本地和远程文件都成功。
它还可以与从advapi32.dll的LogonUser方法获得的模拟身份一起使用。但这需要用户密码,并且我不想从已经登录到应用程序的用户请求密码。
我在做什么错了?
更新:如果共享文件位于主机上,则Windows生成的登录事件(事件查看器中的安全选项卡)将显示正确的用户。如果共享文件位于另一台计算机上,则该计算机上Windows生成的登录事件将显示匿名用户。因此,帐户以某种方式丢失了。
更新2 :如果我在localhost(如url中的localhost)之类的IIS上运行站点,则模拟可以工作。但是,如果我使用ip或站点名称运行它,它将停止工作。
更新3 :Wireshark显示获取委派票证(访问共享文件服务器)的请求失败,错误为“ KRB5KDC_ERR_BADOPTION NT状态:STATUS_NOT_FOUND”。在AD中允许委派应用程序池用户。 在cmd中执行Dir命令时,可以成功检索到未授权的同一票证(用于cifs / fileshareservername)(wireshark显示)。似乎是广告中的问题。
答案 0 :(得分:1)
不能肯定您的操作是否有误,但是我可以告诉您我为完成类似的操作所做的事情。我的.Net网站通常没有WindowsLogin,因此我不得不多跳一点,我认为您可以这样做以促进同一件事,但这也许不是最佳答案。
在登录时(在我的MembershipProvider中),我运行以下代码:
try
{
if (LogonUser(user,domain,password, [AD_LOGIN],
LOGON32_PROVIDER_DEFAULT, ref handle))
{
IntPtr tokenDuplicate = IntPtr.Zero;
if (DuplicateToken(handle, SecurityImpersonation,
ref tokenDuplicate) != 0)
{
// store off duplicate token here
}
}
}
finally
{
if (handle != IntPtr.Zero)
{
CloseHandle(handle);
}
}
然后在需要模拟时,执行以下操作:
var context = WindowsIdentity.Impersonate(tokenDuplicate);
try
{
// do your file access here
}
finally
{
context.Dispose();
}
我必须对该tokenDuplicate变量进行一些有趣的转换。它是一个整数值,但指向存储令牌信息的特定内存地址。只要您已登录,它就保持良好状态。
不知道为什么不能直接对自己的身份进行模仿。我只是知道它对令牌有用,这就是我获取可用于模拟的令牌的方法。
答案 1 :(得分:0)
它开始为我提供以下设置。
IIS:
其他所有不可思议的事情都在Active目录中发生: