【问题标题】:Changing the membership providers ApplicationName during runtime. How?在运行时更改成员资格提供程序 ApplicationName。如何?
【发布时间】:2011-05-02 01:09:41
【问题描述】:

我在这里有一些独特的情况。我正在制作一个将拥有的 Web 应用程序 使用不同的 Web 应用程序凭据登录的能力。例如,您可以登录/注册我的网站,或者您可以登录/注册您的 YouTube 帐户。我没有使用 OpenID,因为在这种情况下我需要访问 YouTube 的数据。

我正在使用 ASP.NET MVC 3 EF4 和自定义成员、角色、配置文件提供程序。

问题是用户名不能是唯一的,因为拥有 YouTube 用户名的人可能与在我的网站上注册的人拥有相同的用户名。所以我通过在我的用户表中指定一个用户类型来解决问题。这几乎是一个复合键(用户 ID 和用户类型)。

我有一个自定义授权属性,用于检查用户所在的角色,但现在我需要实现自定义 IPrincipal,因为我需要传递用户类型。唯一的问题是我在哪里存储它?会议?

最初我认为这就是应用程序表的用途,我暂时成功了,但是读到存在线程问题,而且我在整个地方都遇到了会话错误,这并不是那么好:(

我想知道最好的方法是因为我不能使用提供程序中的重写方法,因为我必须向某些方法添加 UserType 参数,但这会破坏提供程序的功能.

编辑: 我基本上需要能够在运行时以编程方式更改 ApplicationName。我试过这样做,唯一的问题是当我停止开发服务器但打开浏览器然后再次运行我的开发服务器时,它不会保留应用程序名称。

编辑: 我已将我的应用程序更改为使用 OAuth,但我从未找到一个好的解决方案。

【问题讨论】:

  • 好问题。我过去不得不这样做,只有 1/2 的人喜欢我创建的解决方案。当我从我妻子那里拿回我的电脑时,我会给你看一些代码。 :)

标签: c# asp.net asp.net-mvc security


【解决方案1】:

我基本上需要有能力 更改 ApplicationName 在 以编程方式运行时。我试过 这样做,唯一的问题是当 我停止了我的开发服务器,但是 让我的浏览器打开然后运行我的开发 服务器再次它不会保留 应用程序名称。

如果您需要更改 ApplicationName,这意味着您需要在运行时选择一个提供程序。 这样做的唯一方法是不使用单例“成员”,因为它使用 web.config 中定义的提供程序。

而是每次您需要您的提供者时使用:

MembershipProvider userProvider = Membership.Providers[UserProviderName];

只需按照您想要的方式设置 UserProviderName 即可。我会使用自定义全局授权或 preAction 过滤器,它会从某个 cookie 或其他会话变量中检测提供者,并将提供者放入 HttpContextBase.Items 集合中,该集合仅适用于一个请求。

【讨论】:

  • 我喜欢这个解决方案。如果需要,这允许每个“权限”配置略有不同(例如,不同的超时)。好主意!
  • 这个解决方案的唯一缺点是 Membership 类提供了一些非常有用的静态方法,而 MembershipProvider 没有。所有的功能都在那里,只是会员更容易使用。
  • 你是对的,base provider是非常基础的。您的应用程序处于框架未正确支持的 5% 中。
【解决方案2】:

此问题的最佳答案在此处的 stackoverflow 上得到解答:Membership provider with different ApplicationName in area

这是他们使用的代码:

Membership.Providers["MyOtherProvider"].ValidateUser(username, pwd);

【讨论】:

    【解决方案3】:

    瑞恩,

    嗯...您可以通过在用户名字段本身之前添加颁发机构(本地或 YouTube)来解决此问题...示例用户名:“LOCAL/corlettk”、“YOUTUBE/corlettk”?

    好的,您需要一个自定义身份验证器来拆分复杂字符串,并将登录请求轻弹传递给适当的底层身份验证器......但是一旦完成,(我猜)你就准备好了轻松处理更大的授权问题(从您的角度来看)。

    我觉得你是个聪明人……你是否已经考虑过并放弃了这种方法?

    干杯。基思。

    PS:是的,我是一名黑客……但我有一个坏习惯,就是把东西破解成 WORKS……所以他们已经放弃了对我的教育。

    【讨论】:

    • 是的,我已经想到了这一点,但是如果我需要根据用户类型创建页面,现在我必须检查用户名字段并拆分字符串?
    • Hmmmm...if (username.StartsWith("LOCAL/") 对我来说看起来不是太夸张了?但是,如果您发现自己到处都在这样做,那么可能是时候将其纳入您的继承树了。 LocalUser extends UserYouTubeUser extends User 这样每个会话都会做出一次这个小决定。 (是的,我是 Java 人。)
    • 失败了……伙计,你目前的道路几乎完成了。您需要使用IDomainIdentity extends IIdentityIPrinciple.IsInRole 的自定义实现... 是的,我想Credentials 我们是会话的“自然属性”。至少它对我来说“感觉不错”(但我知道关于 MVC3 的一切)。我很想听听真正的专家怎么说。
    • 我认为有更好的抽象。重载用户名的含义/价值/意图是一个坏主意。一般来说,重载 ANY 字段的含义是个坏主意。
    猜你喜欢
    • 2011-11-04
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2011-03-19
    相关资源
    最近更新 更多