Custom membershiprovider validating succesfull but unable to GetUser()
Hello fellow Stackoverflow users,
I'm currently diving into WCF a bit and i've currently setup a POC webservice which uses clientCredentialType="UserName". Since we 开发者_开发知识库some unique wishes we opted for a custom membershipprovider. I am currently implementing one piece by piece. This means that most methods (which aren't used yet) throw not implemented exceptions.
The methods implemented are the Initialize() and ValidateUser() methods, the validate user works, when given the right credentials a person is validate, when i enter bogus they get a security exception.
So far so good.
How ever when i call the GetUser() method (which fetched the username from somewhere and then calls):
public override MembershipUser GetUser(string username, bool userIsOnline)
{
throw new NotImplementedException();
}
As you can see, this is not Implemented (so obviously, it does not work), what frustrates me at the moment is that i can't get this to work because the username which is passed from the underlaying GetUser() method (from the base class MembershipProvider) passes an empty string.
Is there something specific which i'm forgetting? Has anyone else got experience with a custom membershipprovider which tackled this issue?
Edit: added the callstack
at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline) at System.Web.Security.Membership.GetUser() at DirectPay.WCF.Services.Service.TestConnection() in D:\Projects\IBS projects\DirectPay\source\WCF.Services\Service.svc.cs:line 21 at SyncInvokeTestConnection(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
The user is generally supposed to be stored in a custom database of your own which is the point of implementing a custom membership provider. Here is my implementation of the same function:
/// <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);
}
Well, my current answer after beating my head against a wall for a few hours (most likely because i dont know jack about WCF yet ^^) is finding out you can get the current user with:
ServiceSecurityContext.Current.PrimaryIdentity.Name;
The GetUser() method sadly, still does not what i would like, a work around would be to override this method in my custom membershipprovider and fetch the name there. Another option would be to add the following to the GetUser(string username, bool userIsOnline) method:
if(string.IsNullOrWhiteSpace(username))
{
username = ServiceSecurityContext.Current.PrimaryIdentity.Name;
}
I would love to find a way without having to fetch the Username manually, so i won't mark this as an answer as of your, if anything it's a workaround.
精彩评论