在 MVC 中实现自定义身份和 IPrincipal

Posted

技术标签:

【中文标题】在 MVC 中实现自定义身份和 IPrincipal【英文标题】:Implementing a Custom Identity and IPrincipal in MVC 【发布时间】:2010-12-25 10:29:21 【问题描述】:

我有一个基本的 MVC 2 beta 应用程序,我正在尝试实现自定义身份和主体类。

我创建了实现 IIdentity 和 IPrincipal 接口的类,将它们实例化,然后在 Global.asax 的 Application_AuthenticateRequest 中将 CustomPrincipal 对象分配给我的 Context.User。

这一切都成功了,对象看起来不错。当我开始呈现视图时,页面现在失败了。第一个失败是在以下代码行的默认 LogoOnUserControl 视图中:

 [ <%= html.ActionLink("Log Off", "LogOff", "Account") %> ]

如果我把它拉出来,那么它会在不同的“Html.ActionLink”代码行上失败。

我收到的错误是:

类型异常 'System.Runtime.Serialization.SerializationException' 发生在 WebDev.WebHost40.dll 但 未在用户代码中处理

附加信息:类型不是 为会员解决 '模型.实体.用户身份,模型, 版本=1.0.0.0,文化=中性, PublicKeyToken=null'。

为了在 MVC 中使用自定义身份,我需要在身份中实现一些其他属性吗?我尝试在 Identity 类中实现 [Serializable()] 但似乎没有影响。

更新: 我已经尝试了 3-4 种替代方法来实现这一点,但仍然失败并出现同样的错误。如果我直接使用 GenericIdentity/GenericPrincipal 类,它不会出错。

GenericIdentity ident = new GenericIdentity("jzxcvcx");
GenericPrincipal princ = new GenericPrincipal(ident, null);
Context.User = princ;

但这让我无处可去,因为我试图使用 CustomIdentity 来保存几个属性。如果我为我的 CustomIdentity/CustomPrincipal 实现 IIdentity/IPrincipal 接口或继承 GenericIdentity/GenericPrincipal,则会失败并出现上述原始错误。

【问题讨论】:

回复:赞成票...您是否也看到类似的问题? 【参考方案1】:

在网络的帮助下,我想出了这一点 :) 诀窍是您必须在实现 IIdentity 的类中实现 ISerializable 接口。我希望这有助于节省其他人一些时间:)

类声明:

[Serializable]
    public class ForumUserIdentity : IIdentity, ISerializable

ISerializable 的实现:

#region ISerializable Members

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        
            if (context.State == StreamingContextStates.CrossAppDomain)
            
                GenericIdentity gIdent = new GenericIdentity(this.Name, this.AuthenticationType);
                info.SetType(gIdent.GetType());

                System.Reflection.MemberInfo[] serializableMembers;
                object[] serializableValues;

                serializableMembers = FormatterServices.GetSerializableMembers(gIdent.GetType());
                serializableValues = FormatterServices.GetObjectData(gIdent, serializableMembers);

                for (int i = 0; i < serializableMembers.Length; i++)
                
                    info.AddValue(serializableMembers[i].Name, serializableValues[i]);
                
            
            else
            
                throw new InvalidOperationException("Serialization not supported");
            
        

        #endregion

这里是link to the article that has more detail on the "Feature"

【讨论】:

这个功能是废话......它自 2006 年以来就已经存在,并且仍然影响着我的 asp.net mvc-3 应用程序。 这解决了我的问题。 IPrincipal 也是如此。 为什么在反序列化代码中创建一个新的GenericIdentity 而不是CustomIdentity? => `GenericIdentity gIdent = new GenericIdentity(...)' ?? 只是想注意System.ISerializableSystem.Runtime.Serialization.ISerializable 之间的区别。在意识到第二个 (System.Runtime.Serialization.ISerializable) 是我需要的之前,我与第一个斗争了一段时间。【参考方案2】:

我遇到了同样的问题。我通过将创建的主体从 MvcApplication_AuthenticateRequest 移动到 MvcApplication_PostAuthenticateRequest 来解决它。 我不知道为什么/如何,但它解决了问题:)

        void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
    
        HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        
            string encTicket = authCookie.Value;
            if (!String.IsNullOrEmpty(encTicket))
            
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket);
                BiamedIdentity id = new BiamedIdentity(ticket);
                GenericPrincipal prin = new GenericPrincipal(id, null);
                HttpContext.Current.User = prin;
            
        
    

【讨论】:

【参考方案3】:

当我从 MarshalByRefObject 继承我的 Identity 类时,它似乎可以工作。

另请注意:使用 Linq-to-Sql 时没有问题。我切换到 Entity-Framework 并砰的一声,我收到了上面的消息。

【讨论】:

***.com/questions/6503380/… 还有更多关于 marshalbyrefobject 的内容

以上是关于在 MVC 中实现自定义身份和 IPrincipal的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC 5 中实现自定义身份验证

如何在 WCF 服务中实现自定义身份验证

我们如何在 Laravel 中实现自定义的仅 API 身份验证

在 ASP.NET 5 (vNext) MVC 6 中实现自定义路由器

如何在 webflux 中实现自定义身份验证管理器时对未经授权的请求响应自定义 json 正文

可以在 Firebase 3 中实现自定义身份验证属性并将其与安全安全规则一起使用吗?