ASP.NET中用户被拒绝时出现“CustomIdentity”的序列化异常

8
我尝试在现有数据库上实现ASP.NET身份验证和授权。我们有一个网站调用Web服务来获取数据。为了使用Web服务,我需要提供用户名和密码。因此,我决定实现IIdentity和IPrincipal来存储加密的密码,并能够在执行Web服务调用时提供它。将来,我们可能希望使用更多内置于ASP.NET的安全功能,因此我实现了成员资格和角色提供程序,并仅覆盖我需要的内容(ValidateUser和GetRoles)。然而,在通过成员资格提供程序实现验证用户后,我仍然将自己的CustomIdentity设置为Context.User,以便在需要时检索其密码。
只要用户被允许访问页面,它就可以完美地工作。但是当用户被拒绝时,框架会抛出一个Serialization异常,而不是AccessDeniedException。我发现这个链接上描述了更多详细信息的完全相似的行为,但没有答案被发布。
我的异常与上面链接中的完全相同。
成员'CW.CustomAuthentication.CWIdentity,CW.CustomAuthentication,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null'的类型未解析。 描述:在当前Web请求执行期间发生未处理的异常。请查看堆栈跟踪以获取有关错误的更多信息以及其在代码中的起源位置。
异常详细信息:System.Runtime.Serialization.SerializationException:成员'CW.CustomAuthentication.CWIdentity,CW.CustomAuthentication,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null'的类型未解析。
源错误:
在当前Web请求执行期间生成了一个未处理的异常。可以使用下面的异常堆栈跟踪来识别异常的来源和位置。
堆栈跟踪:
[SerializationException: 成员'CW.CustomAuthentication.CWIdentity,CW.CustomAuthentication,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null'的类型未解析。] Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP() +0 Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress() +65 System.Web.HttpRequest.get_UserHostAddress() +18 System.Web.HttpRequest.get_IsLocal() +13 System.Web.Configuration.CustomErrorsSection.CustomErrorsEnabled(HttpRequest request) +86 System.Web.HttpContext.get_IsCustomErrorEnabled() +42 System.Web.Configuration.UrlAuthFailedErrorFormatter.GetErrorText(HttpContext context) +16 System.Web.Security.UrlAuthorizationModule.WriteErrorMessage(HttpContext context) +29 System.Web.Security.UrlAuthorizationModule.OnEnter(Object source, EventArgs eventArgs) +8777783 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

同时使用成员身份(membership)和自定义IIdentity和IPrincipal是否正确?如果不正确,如果我使用成员身份和角色提供程序,应该在哪里添加密码或其他用户数据属性?

最好的问候,

Stephane Erbrech


刚刚添加了异常,如果有帮助的话。 - Stéphane
@serbrech: 谢谢。您的 CW.CustomAuthentication.CWIdentity 可序列化吗?您是否测试过它是否可以使用 BinaryFormatter 进行序列化? - John Saunders
我遇到了同样的问题,并在这里找到了许多有用的信息(和解决方案):http://www.lhotka.net/WeBlog/CommentView,guid,cfcaf6c4-63cf-4cf1-8361-ed3db07496a4.aspx。 - bob
你实际上可以进入你的Web项目属性,转到Web选项卡,并勾选“使用本地IIS服务器”,这将需要以管理员身份运行Visual Studio,以便在加载项目时VS可以创建虚拟目录,但它解决了这个问题。 - Stéphane
确实如此,但是启动需要更多的时间,我尝试实现“获取源代码并运行”的原则... - bob
显示剩余3条评论
5个回答

8
经过进一步测试,根据我发布的链接所说,在从Visual Studio中以调试模式运行时,似乎只有发生了这个错误。如果我将项目设置为在IIS中运行,则错误消失,并且安全实现按预期工作。
---那么这是Visual Studio中实现的轻量级Web服务器中的一个错误吗?---
编辑: 您可以进入Web项目的属性,转到“Web”选项卡,并选中“使用本地IIS服务器”。但是,这将需要您以管理员身份运行Visual Studio并在计算机上安装IIS,以便VS在加载项目时可以在本地IIS服务器中创建虚拟目录。

有人弄清楚为什么会发生这种情况吗? - Moiz Tankiwala

6
在我的情况下,我只需要继承 MarshalByRefObject
public class IcmtrIdentity :  MarshalByRefObject, IIdentity
{
   ...
}

4

这可能不是正确的答案,但我也遇到了这个问题并解决了它。

最初,我只有一个自定义类继承了GenericIdentity(或实现了IIdentity)。当我最终创建了一个继承了GenericPrincipal(或实现了IPrincipal)的自定义类时,一切都起作用了。

我的CustomPrincipal类除了继承自GenericPrincipal并调用了基础构造函数之外什么也没做。

我的CustomPrincipalCustomIdentity类都没有实现任何SerializationISerializable相关的东西。不过,我的类都非常基础。


1
那么解决方案是添加 [Serializable] 吗? - jgauffin
我现在记不清了 - 那是一段时间之前的事了。这取决于您将什么放入您的 CustomPrincipal 或者(更可能的情况是)您的 'CustomIdentity' 中。如果您在其中保存了一个自定义类,那么是的...我想我必须这样做。我已经开始简化我的 CustomIdentity 类,只包含字符串、整数或基本类型。 - Pure.Krome

2
您可以在Web项目的属性中,进入“Web”选项卡,并勾选“使用本地IIS服务器”。但是,这需要您以管理员身份运行Visual Studio并在计算机上安装IIS,以便VS在加载项目时在本地IIS服务器中创建虚拟目录。
当我尝试使用CustomIdentity运行Web应用程序时,我遇到了同样的问题。为了在VS 2008中将项目设置为使用您的IIS,您需要在Web应用程序项目中定义应用程序池的URL。

1
这也可以通过将包含自定义标识的程序集添加到开发计算机上的全局程序集缓存中来解决。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接