在将 aspnet_personalization 与 Windows 身份验证结合使用时,无法弄清楚如何模拟其他用户。
我在我的页面上使用了 asp.net 的个性化框架:
<asp:WebPartManager ID="WebPartManager1" runat="server" >
<Personalization Enabled="True" />
</asp:WebPartManager>
我的页面位于使用 AuthenticationMode="Windows" 的现有 Web 应用程序中(我无法更改,并且 IIS 也设置为 Windows 身份验证)。这个网络应用程序有一个页面,允许超级用户模拟任何其他用户。这是通过操作每次访问数据库时动态构建的连接字符串来实现的。
我的问题是 aspnet_personalization 仍然使用 Windows 身份验证。当我尝试动态编辑 aspnet_personalization 使用的连接字符串时,aspnet 似乎没有使用它——它仍然使用当前 NT 帐户的用户名。
我的 web.config 的配置标签中有以下内容:
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="AnotherConnectionString" connectionString="Data Source=serverName;Initial Catalog=dbName;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<membership>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
applicationName="/"
connectionStringName="AnotherConnectionString" />
</providers>
</membership>
<profile enabled="true" defaultProvider="TableProfileProvider">
<providers>
<clear />
<add name="TableProfileProvider" type="Microsoft.Samples.SqlTableProfileProvider" connectionStringName="AnotherConnectionString" table="aspnet_Profile" applicationName="/" />
</providers>
<!--<properties></properties>-->
</profile>
每当我们模拟用户时,我尝试通过添加如下代码来编辑连接字符串,希望 asp.net 会使用它,但它没有:
Dim settings = ConfigurationManager.ConnectionStrings("AnotherConnectionString")
Dim fi = GetType(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance Or BindingFlags.NonPublic)
fi.SetValue(settings, False)
settings.ConnectionString = "data source=serverName;database=dbName;user id=" & login & "; password=" & password
我确实在包含 webPartManager 的页面的 page_load 上确认“AnotherConnectionString”确实包含所需的用户名,但 asp.net_personalization 仍然使用 NT 用户名调用其存储的过程。
回答:
Stackoverflow 不会让我发布答案。这太荒谬了,所以在我在问题中发布答案后,我将删除我的帐户并鼓励其他人也这样做。
我通过扩展 SqlPersonalizationProvider 解决了这个问题:
Imports System.Web.UI.WebControls.WebParts
Public Class MySqlPersonalizationProvider
Inherits SqlPersonalizationProvider
Protected Overrides Sub LoadPersonalizationBlobs(ByVal webPartManager As System.Web.UI.WebControls.WebParts.WebPartManager, ByVal path As String, ByVal userName As String, ByRef sharedDataBlob() As Byte, ByRef userDataBlob() As Byte)
Dim impersonatedName As String = MySession.UserLoginName()
path = path & "|" & impersonatedName
userName = impersonatedName
MyBase.LoadPersonalizationBlobs(webPartManager, path, userName, sharedDataBlob, userDataBlob)
End Sub
Protected Overrides Sub SavePersonalizationBlob(ByVal webPartManager As System.Web.UI.WebControls.WebParts.WebPartManager, ByVal path As String, ByVal userName As String, ByVal dataBlob() As Byte)
Dim impersonatedName As String = MySession.UserLoginName()
path = path & "|" & impersonatedName
userName = impersonatedName
MyBase.SavePersonalizationBlob(webPartManager, path, userName, dataBlob)
End Sub
End Class
然后在 web.config 中:
<system.web>
<webParts>
<personalization defaultProvider="AspNetSqlPersonalizationProvider">
<providers>
<remove name="AspNetSqlPersonalizationProvider"/>
<add name="AspNetSqlPersonalizationProvider"
type="MyProject.MySqlPersonalizationProvider"
connectionStringName="MyConnectionString"
applicationName="/"></add>
</providers>
</personalization>
</webParts>
<profile enabled="true" defaultProvider="TableProfileProvider">
<providers>
<clear />
<add name="TableProfileProvider" type="Microsoft.Samples.SqlTableProfileProvider" connectionStringName="iCaseHomepage" table="aspnet_Profile" applicationName="/" />
</providers>
</profile>
</system.web>
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="MyConnectionString" connectionString="Data Source=MyServerName;Initial Catalog=MyDatabaseName;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
并在页面上:
<asp:WebPartManager ID="WebPartManager1" runat="server" >
<Personalization Enabled="True" />
</asp:WebPartManager>