我们的网站目前设置为使用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帐户,和 选中所需访问的框。
来源错误:
执行期间生成了未处理的异常 当前的网络请求。有关的来源和位置的信息 可以使用下面的异常堆栈跟踪来识别异常。
堆栈追踪:
[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,Boolean& completedSynchronously)+266----------------------------------------------- ---------------------------------版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.0.30319.1022
此外,服务器上的事件查看器显示了这一点。
Web事件提供程序抛出以下异常 ' EventLogProvider'在应用程序' / Form1' (在申请中 生命周期每个提供者最多记录一个例外 实例):
System.UnauthorizedAccessException:尝试执行 未经授权的操在 System.Security.Principal.WindowsIdentity.get_AuthenticationType()
在 System.Web.Management.EventLogWebEventProvider.AddWebRequestInformationDataFields(ArrayList的 dataFields,WebRequestInformation reqInfo)at System.Web.Management.EventLogWebEventProvider.ProcessEvent(WebBaseEvent eventRaised)at System.Web.Management.WebBaseEvent.RaiseInternal(WebBaseEvent eventRaised,ArrayList firingRuleInfos,Int32 index0,Int32 index1)
根据这篇文章(The following exception was thrown by the web event provider 'EventLogProvider')我认为问题必须是我的代码试图写入EventLog但没有权限。但是,遵循artcile(http://support.thycotic.com/KB/a220/giving-application-pool-access-to-event-log.aspx)中列出的步骤后,仍然无法正常工作。
我希望有人能告诉我我的代码在ApplicationPoolIdentity无法访问的服务器上尝试做什么,并且我们可以确定需要授予哪些额外权限ApplicationPoolIdentity。
答案 0 :(得分: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 article注意到LocalSystem已经有了这个,这就是为什么它是帐户的原因。
文章中有很多警告说明为什么你不应该授予这个特权。
这确实让我想知道你为什么要这样做?