【问题标题】:Custom membershiprovider validating succesfull but unable to GetUser()自定义会员提供者验证成功但无法 GetUser()
【发布时间】:2011-08-12 13:50:39
【问题描述】:

大家好,Stackoverflow 用户,

我目前正在深入研究 WCF,并且我目前设置了一个使用 clientCredentialType="UserName" 的 POC Web 服务。由于我们有一些独特的愿望,我们选择了自定义会员提供者。我目前正在一件一件地实施。这意味着大多数方法(尚未使用)会抛出未实现的异常。

实现的方法是 Initialize() 和 ValidateUser() 方法,验证用户工作,当给定正确的凭据时,一个人被验证,当我输入伪造时,他们得到一个安全异常。

到目前为止一切顺利。

当我调用 GetUser() 方法(从某处获取用户名然后调用)时:

public override MembershipUser GetUser(string username, bool userIsOnline)
{
    throw new NotImplementedException();
}

如您所见,这没有实现(很明显,它不起作用),目前让我感到沮丧的是我无法让它工作,因为从底层 GetUser() 传递的用户名方法(来自基类 MembershipProvider)传递一个空字符串。

有什么我忘记的具体内容吗?是否有其他人使用过解决此问题的自定义会员服务提供商的经验?

编辑:添加调用堆栈

在 System.Web.Security.Membership.GetUser(字符串用户名,布尔值 userIsOnline) 在 System.Web.Security.Membership.GetUser() 在 D:\Projects\IBS 中的 DirectPay.WCF.Services.Service.TestConnection() projects\DirectPay\source\WCF.Services\Service.svc.cs:第 21 行 SyncInvokeTestConnection(Object , Object[] , Object[] ) 在 System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象 实例,Object[] 输入,Object[]& 输出)在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

【问题讨论】:

  • 如何调用GetUser 方法?您可以发布导致调用此方法的调用堆栈吗?
  • 这里是调用栈(我希望这就是你的意思,我不是调试明星:x)
  • 不,我没有,因为这不是抽象方法,它是在 MembershipProvider 中实际实现的方法。我希望实际从...上下文中获取用户名的逻辑?这有点卡住了,我觉得我需要在验证时在某处设置用户名......但我不知道在哪里设置它,所以 GetUser() 将能够获取它>.
  • 好的,我找到了一种在我正在调用的 TestConnection 方法中获取名称的方法:ServiceSecurityContext.Current.PrimaryIdentity.Name 有效。现在我仍然不明白为什么 GetUser() 不这样做......所以我让它保持打开状态。理想情况下,我不希望我的方法打扰用户名和其他东西。

标签: c# .net wcf asp.net-membership


【解决方案1】:

用户通常应该存储在您自己的自定义数据库中,这是实现自定义成员资格提供程序的关键。这是我对相同功能的实现:

/// <summary>
/// Gets information from the data source for a user.
/// Provides an option to update the last-activity date/time stamp for the user.
/// </summary>
/// <param name="username">The name of the user to get information for.</param>
/// <param name="userIsOnline">true to update the last-activity date/time 
/// stamp for the user; false to return user information without updating 
/// the last-activity date/time stamp for the user.</param>
/// <returns>A MembershipUser object populated with the specified
/// user's information from the data source.</returns>
public override MembershipUser GetUser(string username, bool userIsOnline)
{
    // Get User from my custom database
    User user = Database.User.GetUser(username);

    // Convert User to MebmershipUser (or return null if User == null)
    return user == null ? null : new MembershipUser(
        "CustomMembershipProvider",
        user.UserName, 
        user.UserID,
        user.Email,
        string.Empty, 
        user.Comments, 
        user.Active,
        false, 
        user.CreatedDate, 
        user.LastLoginDate, 
        DateTime.Now, 
        user.LastPasswordChangedDate, 
        DateTime.Now);
}

【讨论】:

  • 是的,我想我还不够清楚。该方法尚未实现,只是因为我想先获取用户名。找到不需要任何用户名的 GetUser() 方法,因此检查最后传递了什么用户名。当我们使用 SqlMembershipProvider 时,Thread.CurrentPrincipal.Identity.Name 会返回用户名,目前这也是一个 string.Empty。同样适用于传递给此方法的内容。基本上我可以用这种方法编写我想要的所有实现,但这对我没有好处,因为我没有得到正确的用户名(或根本没有)。
  • 一般是User.Identity.Name作为username传递。如果您有自定义数据库,则获取该用户并将其返回。如果您只是从 ASP.Net 用户数据库中获取用户,那么您实现自定义 MembershipProvider 的原因是什么?
  • 我们有一个自定义数据库,但我们必须根据名称获取此用户。问题是当前 GetUser() 没有获得传递给它的名称。尽管呼叫已经过验证,但我觉得也许我需要在验证期间设置一些东西。或者获取已验证的当前请求的名称,就像我过去通过 Thread.CurrentPrincipal.Identity.Name 所做的那样。
  • @F.B.十凯特,调用函数是什么?
  • 一种称为:公共字符串 TestConnection() 的方法,它作为 WCF 服务 [OperationContract] 公开。正如我一直在阅读的那样,对 wsHttpBinding 端点中的每个调用都进行了整个验证,并且调用已成功验证,但这就是事情结束的地方。
【解决方案2】:

好吧,我在用头撞墙几个小时后(很可能是因为我还不知道杰克关于 WCF ^^)的当前答案是发现您可以通过以下方式获得当前用户:

ServiceSecurityContext.Current.PrimaryIdentity.Name;

遗憾的是,GetUser() 方法仍然不是我想要的,解决方法是在我的自定义成员资格提供程序中覆盖此方法并在那里获取名称。另一种选择是将以下内容添加到 GetUser(string username, bool userIsOnline) 方法中:

if(string.IsNullOrWhiteSpace(username))
{
   username = ServiceSecurityContext.Current.PrimaryIdentity.Name;
}

我很想找到一种无需手动获取用户名的方法,所以我不会将此标记为您的答案,如果有的话,这是一种解决方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-26
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多