MVC 4 template with custom membership provider

Bobby Cannon picture Bobby Cannon · Aug 19, 2012 · Viewed 12.3k times · Source

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>

Answer

Bobby Cannon picture Bobby Cannon · Aug 19, 2012

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.