如何在 ASP.NET MVC 中实现基于 ID 的用户系统(成员身份、授权等)?
我已经思考了很长一段时间如何解决在使用 ASP.NET MVC 时实现基于 ID 的用户系统的问题。我的目标,就像 StackOverflow 的系统一样,如下:
- 允许用户更改他们的昵称,而不受“避免重复”限制。
- 允许用户通过OpenID进行身份验证(暂时不使用密码)。
我想避免尽可能多的返工,所以我首先想到使用会员资格、角色和(可能)个人资料提供程序,但我发现它们是基于用户名的。 我想通过使用用户名字段来存储 ID 并在基于密码的方法等上抛出 UnsupportedException 来适应 SqlMembershipProvider 的地狱,以便能够使用其他系统。但感觉笨拙且笨拙(如果可能的话)。
另一方面,也许我应该建立自己的用户系统,但我不确定即使我不能使用提供程序,我是否仍然可以使用 MVC 的一些功能(将我的代码插入 MVC 在某个地方,我可以立即想到 AuthorizeAttribute)。
所以我想知道是否有人遇到过同样的设计问题,以及他们提出了什么解决方案。
越详细越好!
I have been thinking for a good while about how to tackle the problem of implementing an ID based user system while using ASP.NET MVC. My goals, much like StackOverflow's system are as follows:
- Allow the users to change their nicknames without the "avoid duplicate" restriction.
- Allow the users to authenticate via OpenID (not with password for the time being).
I wanted to avoid as much rework as possible, so I at first thought of using the membership, role and (perhaps) profile providers, but I found they were username based.
I thought of adapting the hell out of the SqlMembershipProvider, by using the username field to store the IDs and throwing UnsupportedException on password based methods and the like, just so as to be able to use the other systems. But it feels unwieldy and kludgy (if possible to do at all).
On the other hand, maybe I should roll up my own user system, but I'm not sure if even if I can't use the providers, I can still use some of MVC's features (plug my code in with MVC somewhere, I can think of AuthorizeAttribute off the top my head).
So I was wondering if anyone had run into the same design problem, and what solutions they had come up with.
The more detail the better!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我必须为客户建立一个快速的会员系统,他们有一些要求,不允许我立即使用内置功能,也不允许我有时间构建他们想要的东西。我计划最终推出一个完整的会员管理系统,但像你一样,我现在需要一些东西。我采用了以下计划,最终允许我将内置提供商换成自己的提供商 - 时间限制和截止日期很糟糕:
我有自己的个人用户表 (PT) - MembershipId、用户名、电子邮件、多余的个人资料信息。这是应用程序用于任何用户信息的内容。它是一个类,它可以被缓存、保存在http上下文、cookie中——但是你想处理你的用户信息。
然后,我设置 SqlProfileProvider 来进行身份验证、授权和角色。我不使用配置文件提供程序(即使对于简单的设置),因为它在 MVC 中是一个痛苦。我没有对内置提供程序进行任何更改。这就是我用于身份验证和授权的方法。
创建用户时,我的代码执行以下操作:
登录时,我从 PT 获取 MembershipId,使用 MembershipId 和密码验证会员身份,然后就完成了。
删除用户时,我执行以下操作:
并且它按预期工作:)
一些事情:
User.Identity.Name 将是 MembershipId (Guid)。这用于登录和角色管理。我的PT是保存用户信息(保存密码)的地方。我可以更改用户名、电子邮件等,而不会影响成员身份或角色,因为成员身份基于 PT 的主键。
登录需要额外的数据库命中,因为您需要查询 PT 以获取要验证的 MembershipId(您可以缓存)。
内置的身份验证系统确实很重 - 如果您查看存储过程,您会看到它验证用户所经历的所有环节。我建议最终摆脱它。但在紧张的情况下,它做得很好——如果你没有一百万用户,我认为这不会是一个问题。
我没有考虑 OpenId,我不确定如何集成它,尽管我认为您可能可以做与上面相同的事情,而不是根据实际凭据进行验证(在它们返回经过验证的 OpenId 后),只需登录用户使用 MembershipId(不验证会员身份)。
对我来说,这背后的要点是该应用程序使用自定义用户模型,允许更改用户名、电子邮件、姓名等,而不影响身份验证和角色。当我准备好更改为完整系统时,我可以更改它,而不必担心对应用程序的影响。
I had to set up a quick membership system for a client, they had some requirements that didn't allow me to use the built-in right off the bat nor the time to build what they wanted. I have plans to eventually roll-out a complete membership management system, but like you, I needed something now. I went with the following plan, which will, eventually, allow me to swap out the built-in providers for my own - time constraints and deadlines suck:
I have my own Personal User Table (PT) - MembershipId, UserName, Email, superflous profile info. This is what the app uses for any user information. It's a class, it can be cached, saved in the http context, cookie - however you want to handle your user info.
I then set up the SqlProfileProvider for authentication, authorization, and roles. I don't use the profile provider (even for trivial settings) because it's a pain in MVC. I made no changes to the built-in providers. This is what I'm using for authentication and authorization.
When creating a user, my code does the following:
On login, I get the MembershipId from PT, validate against Membership with the MembershipId and the password and I'm done..
When deleting a user, I do the following:
And it works as expected :)
A few things:
User.Identity.Name will be the MembershipId (Guid). This is used for SignIn and Role management. My PT is where the user's info (save the password) is saved. I can change user names, emails, etc with no impact on Membership or Roles because Membership is based on the PrimaryKey from PT.
The signin requires an extra DB hit because you need to query PT to get the MembershipId to validate against (you could cache).
The built-in auth system is really heavy - if you look at the sprocs you will see all the hoops it goes through to validate a user. I'd recommend eventually getting away from it. But in a tight spot, it does a good job - and if you don't have a milion users, I don;t think it'd be a problem.
I didn't consider OpenId and I'm not sure how you would integrate it, although I think you could probably do the same thing as above and instead of validating against actual credentials (after they come back validated form OpenId) just log in the user using the MembershipId (don;t validate against Membership).
For me, the main point behind this was that the app uses a custom user model, allowing for changes to user name, email, names, etc. Without impacting the auth and roles. When I am ready to change to the complete system, I can change it without worrying about the impact to the app.
Kenji,
我建议您查看一些 现有的 ASP.NET OpenID 提供程序。让它们与 MVC 一起工作应该相当容易。
埃里克
Kenji,
I would recommend looking at some of the existing OpenID providers for ASP.NET. It should be fairly easy to make them work with MVC.
Erick
放弃使用 SqlMembershipProvider。它真正为您提供的唯一东西是开箱即用的管理界面。它带来的其余部分将是一个麻烦。
Forgo the use of SqlMembershipProvider. The only thing it would really offer you is an out of the box admin interface. The rest that it brings would be a nuisance.
只需使用 sql 成员身份提供程序并添加存储过程即可在数据库级别更改用户名。
Just use the sql membership provider and add a stored proc to change the username at the database level.