C# 自定义MembershipProvider验证成功,但无法获取用户()

C# 自定义MembershipProvider验证成功,但无法获取用户(),c#,.net,wcf,asp.net-membership,C#,.net,Wcf,Asp.net Membership,各位用户好 我目前正在深入研究WCF,目前我已经建立了一个使用clientCredentialType=“UserName”的POC Web服务。由于我们有一些独特的愿望,我们选择了定制会员资格提供商。我目前正在一件一件地实施。这意味着大多数方法(尚未使用)抛出未实现的异常 实现的方法是Initialize()和ValidateUser()方法,validate用户可以工作,当给某人提供正确的凭据时,他们可以进行验证,当我输入false时,他们会得到一个安全异常 到目前为止还不错 当我调用Get

各位用户好

我目前正在深入研究WCF,目前我已经建立了一个使用clientCredentialType=“UserName”的POC Web服务。由于我们有一些独特的愿望,我们选择了定制会员资格提供商。我目前正在一件一件地实施。这意味着大多数方法(尚未使用)抛出未实现的异常

实现的方法是Initialize()和ValidateUser()方法,validate用户可以工作,当给某人提供正确的凭据时,他们可以进行验证,当我输入false时,他们会得到一个安全异常

到目前为止还不错

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

正如您所看到的,这没有实现(很明显,它不起作用),目前让我感到沮丧的是,我无法实现这一点,因为从底层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(对象,对象[],对象[])位于 System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象 实例、对象[]输入、对象[]和输出) System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& (rpc)


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

/// <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);
}
//
///从数据源获取用户的信息。
///提供一个选项来更新用户的最后活动日期/时间戳。
/// 
///要为其获取信息的用户的名称。
///如果为true,则更新上次活动日期/时间
///用户盖章;false返回用户信息而不进行更新
///用户的最后活动日期/时间戳。
///使用指定的
///来自数据源的用户信息。
公共覆盖成员身份用户GetUser(字符串用户名,bool userIsOnline)
{
//从我的自定义数据库获取用户
User=Database.User.GetUser(用户名);
//将用户转换为MebmershipUser(如果User==null,则返回null)
返回用户==null?null:新成员身份用户(
“CustomMembershipProvider”,
user.UserName,
user.UserID,
用户邮箱,
字符串。空,
用户评论,
user.Active,
假,,
user.CreatedDate,
user.lastloginandate,
日期时间,现在,
user.LastPasswordChangedDate,
日期时间(现在);
}

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

/// <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);
}
//
///从数据源获取用户的信息。
///提供一个选项来更新用户的最后活动日期/时间戳。
/// 
///要为其获取信息的用户的名称。
///如果为true,则更新上次活动日期/时间
///用户盖章;false返回用户信息而不进行更新
///用户的最后活动日期/时间戳。
///使用指定的
///来自数据源的用户信息。
公共覆盖成员身份用户GetUser(字符串用户名,bool userIsOnline)
{
//从我的自定义数据库获取用户
User=Database.User.GetUser(用户名);
//将用户转换为MebmershipUser(如果User==null,则返回null)
返回用户==null?null:新成员身份用户(
“CustomMembershipProvider”,
user.UserName,
user.UserID,
用户邮箱,
字符串。空,
用户评论,
user.Active,
假,,
user.CreatedDate,
user.lastloginandate,
日期时间,现在,
user.LastPasswordChangedDate,
日期时间(现在);
}

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

ServiceSecurityContext.Current.PrimaryIdentity.Name;
遗憾的是,GetUser()方法仍然不是我想要的,一个解决办法是在我的自定义membershipprovider中重写此方法并在那里获取名称。另一个选项是将以下内容添加到GetUser(字符串用户名,bool userIsOnline)方法中:


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

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

ServiceSecurityContext.Current.PrimaryIdentity.Name;
遗憾的是,GetUser()方法仍然不是我想要的,一个解决办法是在我的自定义membershipprovider中重写此方法并在那里获取名称。另一个选项是将以下内容添加到GetUser(字符串用户名,bool userIsOnline)方法中:


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

是的,我想我还不够清楚。这个方法还没有实现,只是因为我想先得到用户名。找到了不需要任何用户名的GetUser()方法,因此检查了最后传递的用户名。当我们使用SqlMembershipProvider线程时,CurrentPrincipal.Identity.Name将返回用户名current