0

我们的网站目前设置为使用 Windows 身份验证。当请求到达我们的代码时会自动设置用户安全主体,并且对特定文件的授权由我们的 web.config 中的授权元素控制。

我们现在被要求在我们的服务器上安装 siteminder 来处理身份验证。因此,不会自动设置用户安全主体,并且我们未经修改的代码不知道用户是谁来确定授权。

我开发了以下代码来解决该问题。它从 siteminder 注入请求的标头中获取用户名,并创建用户安全主体。

protected void Application_AuthenticateRequest(object sender, EventArgs e)

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            string userSSO = null;

            //Siteminder gives us user like in this format domain\user
            userSSO = HttpContext.Current.Request.Headers["SMUser"];

            if (userSSO != null && userSSO != "")
            {
                //we have to take the id in the format siteminder gives us and switch it over to upn format like this user@domain
                string [] delimiters = {"\\"};
                string [] aryUserSSO = userSSO.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                string UPN = aryUserSSO[1] + "@" + aryUserSSO[0] + "domain.com";


                //now we create identity and princal objects using the UPN
                WindowsIdentity identity = new WindowsIdentity(UPN, "WindowsAuthentication");

                WindowsPrincipal principal = new WindowsPrincipal(identity);

                HttpContext.Current.User = principal;
            }
        }

只要将 IIS 上的 AppPool 的标识设置为作为 LocalSystem 运行,此代码就可以正常工作。但是,如果您将 AppPool 的标识设置为具有较少权限的任何其他内容,例如 NetworkService 或 ApplicationPoolIdentity,您会收到以下错误消息。

“/Form1”应用程序中的服务器错误。

试图执行未经授权的操作。说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.UnauthorizedAccessException:试图执行未经授权的操作。

ASP.NET 无权访问请求的资源。考虑向 ASP.NET 请求标识授予对资源的访问权限。ASP.NET 有一个基本进程标识(通常是 IIS 5 上的 {MACHINE}\ASPNET 或 IIS 6 和 IIS 7 上的网络服务,以及 IIS 7.5 上配置的应用程序池标识),如果应用程序不是模拟的,则使用该标识。如果应用程序通过 模拟,则身份将是匿名用户(通常是 IUSR_MACHINENAME)或经过身份验证的请求用户。

要授予 ASP.NET 对文件的访问权限,请在资源管理器中右键单击该文件,选择“属性”并选择“安全”选项卡。单击“添加”以添加相应的用户或组。突出显示 ASP.NET 帐户,然后选中所需访问权限的复选框。

源错误:

在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息。

堆栈跟踪:

[UnauthorizedAccessException:试图执行未经授权的操作。]
System.Security.Principal.WindowsIdentity.get_AuthenticationType() +300 System.Web.Hosting.IIS7WorkerRequest.SetPrincipal(IPrincipal user, IntPtr pManagedPrincipal) +181
System.Web.HttpContext.SetPrincipalNoDemand( IPrincipal principal, Boolean needToSetNativePrincipal) +701
System.Web.HttpContext.set_User(IPrincipal value) +49
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +182 System.Web.HttpApplication.ExecuteStep(IExecutionStep step , 布尔值和完成同步)+266

-------------------------------------------------- ------------------ 版本信息:Microsoft .NET Framework 版本:4.0.30319;ASP.NET 版本:4.0.30319.1022

此外,服务器上的事件查看器也显示了这一点。

应用程序“/Form1”中的 Web 事件提供程序“EventLogProvider”引发了以下异常(在应用程序生命周期中,每个提供程序实例最多记录一个异常):

System.UnauthorizedAccessException:试图执行未经授权的操作。
在System.Web.Management.EventLogWebEventProvider.AddWebRequestInformationDataFields(ArrayList dataFields, WebRequestInformation reqInfo) 在 System.Web.Management.EventLogWebEventProvider.ProcessEvent(WebBaseEvent eventRaised) 在 System.Web.Management的 System.Security.Principal.WindowsIdentity.get_AuthenticationType() 。 WebBaseEvent.RaiseInternal(WebBaseEvent eventRaised,ArrayList 触发规则信息,Int32 index0,Int32 index1)

根据这篇文章(Web 事件提供程序“EventLogProvider”引发了以下异常),我认为问题一定是我的代码试图写入 EventLog 但没有权限。但是,按照文章中概述的步骤 ( http://support.thycotic.com/KB/a220/giving-application-pool-access-to-event-log.aspx ) 仍然不起作用。

我希望有人能告诉我,我的代码在服务器上试图做什么,而 ApplicationPoolIdentity 无权执行,并且我们可以弄清楚需要向 ApplicationPoolIdentity 授予哪些额外权限。

4

1 回答 1

2

您的问题不是 Siteminder,而是您想模拟从 siteminder 标头中获取的任意用户帐户的名称。

 //now we create identity and princal objects using the UPN
 WindowsIdentity identity = new WindowsIdentity(UPN, "WindowsAuthentication");
 WindowsPrincipal principal = new WindowsPrincipal(identity);
 HttpContext.Current.User = principal;

为此,您需要“充当操作系统的一部分”权限。

正如msdn 文章所指出的那样,LocalSystem 已经有了这个,这就是为什么当它是帐户时它可以工作的原因。

文章中有很多关于为什么不应该授予该特权的警告。

这确实让我想知道你为什么要这样做?

于 2014-08-19T16:55:45.163 回答