Asp.net mvc 具有自定义成员资格的MVC.NET应用程序的实施审查

Asp.net mvc 具有自定义成员资格的MVC.NET应用程序的实施审查,asp.net-mvc,asp.net-membership,Asp.net Mvc,Asp.net Membership,我想听听是否有人看到我如何在这个基于Oracle的MVC.NET应用程序中实现安全性的任何问题,无论是安全性问题、并发性问题还是可伸缩性问题 首先,我实现了一个CustomOracleMembershipProvider来处理成员资格存储的数据库接口 我实现了一个名为User的自定义主体,它实现了IPrincipal,并且它有一个角色哈希表 我还创建了一个名为AuthCache的单独类,它为用户对象提供了一个简单的缓存。它的目的很简单,可以避免返回数据库,同时将缓存与web层或数据层分离。(这样

我想听听是否有人看到我如何在这个基于Oracle的MVC.NET应用程序中实现安全性的任何问题,无论是安全性问题、并发性问题还是可伸缩性问题

首先,我实现了一个CustomOracleMembershipProvider来处理成员资格存储的数据库接口

我实现了一个名为User的自定义主体,它实现了IPrincipal,并且它有一个角色哈希表

我还创建了一个名为AuthCache的单独类,它为用户对象提供了一个简单的缓存。它的目的很简单,可以避免返回数据库,同时将缓存与web层或数据层分离。(这样我可以在MVC.NET、WCF等之间共享缓存)

MVC.NET stockMembershipService使用CustomOracleMembershipProvider(在web.config中配置),并且MembershipServiceFormsService共享对singleton AuthCache的访问

我的AccountController.LogOn()方法:

1) 通过MembershipService验证用户。Validate()方法还将角色加载到user.roles容器中,然后将用户缓存在AuthCache中

2) 通过FormsService将用户登录到Web上下文。SignIn()访问AuthCache(而不是数据库)以获取用户,将HttpContext.Current.user设置为缓存的用户主体

在global.asax.cs中,实现了应用程序_AuthenticateRequest()。它解密FormsAuthenticationTicket,通过ticket.Name(用户名)访问AuthCache,并通过设置Context.User=AuthCache中的用户来设置主体

简而言之,所有这些类都共享AuthCache,对于线程同步,我在cache-store方法中有一个lock()。读取方法中没有锁

自定义成员资格提供程序不知道缓存,MembershipService不知道任何HttpContext(因此可以在web应用程序之外使用),FormsService除了访问AuthCache来设置上下文外,不使用任何自定义方法。初始登录的用户,因此,它不依赖于特定的成员资格提供者


我现在看到的主要情况是,如果用户从多个会话登录,AuthCache将共享一个用户对象。因此,我可能必须将密钥从仅UserId更改为其他内容(可能使用表单中的内容作为密钥身份证?)。

为什么要使用哈希表作为角色?一个简单的列表可能会更快地搜索,除非你期望人们有更多的角色。如果可以提前预测所有角色,那么使用位掩码/标志枚举会更好

您应该尽量避免编写自己的锁定机制,因为它很容易出错。使用新的System.Collections.Concurrent类,或者如果您必须使用自己的类,那么请确保使用Interlocked(因为所有其他锁定机制都非常昂贵)

缓存应使用WeakReference封装,以允许对条目进行GCD,并支持在缺少条目时从数据库检索用户信息。如果您需要分布式缓存,可以查看Velocity

共享用户对象可能不是问题,但可能不是推荐的策略。许多数据库访问框架将跟踪在会话或工作单元中检索到的对象,因此跨会话共享对象会有问题。如果确实要共享用户对象,请确保它们不可变


最后,我个人鄙视整个成员资格提供者API,因为它使用GUI进行标识,而用户配置文件的默认SQL Server数据库设计非常糟糕(也称为性能杀手)。这似乎不是您所关心的问题,因为您已经推出了自己的(db和实现),但您可能希望评估实现API是否有任何真正的好处,或者它是否主要是将您束缚在特定的做事方式上。

+1感谢您的有用反馈。我同意会员资格提供者,我不使用微软的模式,即使是甲骨文。我的多租户数据库的要求比用户ID/密码更复杂。我实现提供者的主要原因是为了获得声明性角色。至于并发性,嗯,是的,它很容易出错,但在简单的情况下不难纠正;我只是将存储序列化到缓存中。即使在负载下,我也不希望每分钟有超过几个新的登录。我来看看你的建议。关于弱引用的好主意,我没有考虑过。现在我对框架有了更好的理解,我意识到要让声明性角色工作,我所需要的只是自定义主体,而不是完全成员资格提供者。