Bobby Cannon
Bobby Cannon

Reputation: 6933

MVC 4 template with custom membership provider

What I'm wanting to do is use the default MVC 4 template that just shipped with Visual Studio 2012 as base for my new project. However I want to replace the SQL provider with custom membership provider so I can access my RavenDB to get my users. I've implemented the custom provider as I have before but the WebSecurity methods are throwing the following exception.

This line of code:

ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));

Specifically the method:

WebSecurity.GetUserId

Is throwing this exception:

You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class. This call should be placed in an _AppStart.cshtml file in the root of your site.

Now I cannot call InitializeDatabaseConnection because my provider isn't a SQL provider. This method expects a SQL provider and a SQL connection string. Is this a common problem or am I missing something? Why does WebSecurity have to be initialized and why does it expect to only be connected using a SQL provider?

Am I going to have to just change the code to not use the WebSecurity class?

I've been at this all day and I'm pretty tired. I hope I haven't overlooked something simple. Maybe one more rum and coke will help...

Update: 08/19/2012

I decompiled the GetUserId method and found the only reason it's failing is because of the VerifyProvider call.

public static int GetUserId(string userName)
{
    WebSecurity.VerifyProvider();
    MembershipUser user = Membership.GetUser(userName);
    if (user == null)
        return -1;
    else
        return (int) user.ProviderUserKey;
}

private static ExtendedMembershipProvider VerifyProvider()
{
    ExtendedMembershipProvider membershipProvider = Membership.Provider as ExtendedMembershipProvider;

    if (membershipProvider == null)
        throw new InvalidOperationException(WebDataResources.Security_NoExtendedMembershipProvider);

    membershipProvider.VerifyInitialized();
    return membershipProvider;
}

Now the only reason it's failing in the VerifyProvider method is because of the call to VerifyInitialized which I cannot override in my membership provider. Also if it's not calling my provider then I'm not sure what code is being called when VerifyInitialized is processed.

internal virtual void VerifyInitialized()
{
}

I'm removing all the other membership providers in the Web.Config. At least I think I am. Here is the entry.

<membership defaultProvider="RavenMembershipProvider">
    <providers>
        <clear />
        <add name="RavenMembershipProvider" type="BigGunsGym.Infrastructure.Providers.RavenMembershipProvider" />
    </providers>
</membership>

Upvotes: 5

Views: 12336

Answers (2)

dave heywood
dave heywood

Reputation: 791

I also had the same problem, after creating a new Action to create users....

action was...

public ActionResult CreateUsers()
{
string username = "blah blah auto create";
string password = "blah blah auto create";
WebSecurity.CreateUserAndAccount(username, password);
}

but it just needed the filter attrib adding

[InitializeSimpleMembership]
public ActionResult CreateUsers()
{
string username = "blah blah auto create";
string password = "blah blah auto create";
WebSecurity.CreateUserAndAccount(username, password);
}

Upvotes: 1

Bobby Cannon
Bobby Cannon

Reputation: 6933

Turns out I had my provider inheriting from SimpleMembershipProvider instead of ExtendedMembershipProvider. I thought it would be OK since SimpleMembershipProvider inherits ExtendedMembershipProvider but it did not work.

After changing my provider to inherit from ExtendedMembershipProvider the error went away.

Upvotes: 5

Related Questions