0

I'm new to web development and particular to web API (rest service) development. I've studied how to develop MVC projects using entity framework and membership. When I needed to use authentication and authorization I simply added the AUTHORIZE attribute to the controller/action. In order to add user, I've used the Register action on the Account controller.

Now I have a new project which is a web API project in MVC 5 (Visual studio 2013). I've added a new user using the default api action - Register (using fidler). Now, I'm trying to simply use a get method to read some data, but when adding the AUTHORIZE attribute and also add the correct user name and password I'm keep getting 401 (unauthorized) response. And then I've founded this thread:

ASP.NET MVC 4 Web API Authentication with Membership Provider

Bur now, the method Membership.ValidateUser(username, password) always returning false, I'm assuming I have to define the membership database, where do I do it?

Here is the full code:

using System;
using System.Net.Http;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;


public class BasicAuthenticationMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage>         SendAsync(HttpRequestMessage     request, CancellationToken cancellationToken)
{
    var authHeader = request.Headers.Authorization;

    if (authHeader == null)
    {
        return base.SendAsync(request, cancellationToken);
    }

    if (authHeader.Scheme != "Basic")
    {
        return base.SendAsync(request, cancellationToken);
    }

    var encodedUserPass = authHeader.Parameter.Trim();
    var userPass = Encoding.ASCII.GetString(Convert.FromBase64String(encodedUserPass));
    var parts = userPass.Split(":".ToCharArray());
    var username = parts[0];
    var password = parts[1];

    if (!Membership.ValidateUser(username, password))
    {
        return base.SendAsync(request, cancellationToken);
    }

    var identity = new GenericIdentity(username, "Basic");
    string[] roles = Roles.Provider.GetRolesForUser(username);
    var principal = new GenericPrincipal(identity, roles);
    Thread.CurrentPrincipal = principal;
    if (HttpContext.Current != null)
    {
        HttpContext.Current.User = principal;
    }

    return base.SendAsync(request, cancellationToken);
}
}

Here is where I've added the handler:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        GlobalConfiguration.Configuration.MessageHandlers.Add(
new BasicAuthenticationMessageHandler()
);
    }
}

Thanks in advance, Shaul

Community
  • 1
  • 1
Shaul Zuarets
  • 839
  • 2
  • 10
  • 20

2 Answers2

1

Define the Membership database in the Web.Config as follows :

<connectionStrings>
<add name="test_connStr" connectionString="" />
</connectionStrings>

<system.web>
<membership defaultProvider="test_provider">
      <providers>
        <clear />
        <add name="test_provider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="test_connStr" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" applicationName="/" />
      </providers>
    </membership>
</system.web>

Set the connectionString to Membership database connection string. And the connectionStringName should be the name of the connection string defined.

EDIT :

Sorry I am a bit late on this. Check the contents of aspnet_SchemaVersions table. It should contain the following :

common              1   True
health monitoring   1   True
membership          1   True
personalization     1   True
profile             1   True
role manager        1   True

As shown in this answer.

Community
  • 1
  • 1
sth
  • 146
  • 8
  • I did that, and now I get the following:requires a database schema compatible with schema version '1'. However, the current database schema is not compatible with this version. You may need to either install a compatible schema with aspnet_regsql.exe (available in the framework installation directory), or upgrade the provider to a newer version. – Shaul Zuarets Aug 04 '15 at 13:41
  • My DB has been created by an MVC 3 schema – Shaul Zuarets Aug 04 '15 at 13:42
  • OK, it seems, my DB schema is simple membership, how do I change the provider? – Shaul Zuarets Aug 04 '15 at 13:53
0

In order to use simple membership provider I've used this simple tutorial: http://monox.mono-software.com/blog/post/Mono/226/Adding-ASP-NET-SimpleMembership-to-an-existing-MVC-4-application/ But it still had a simple bug which was solved by adding the Nuget package: Microsoft.AspNet.WebHelpers.

That's all.

Shaul Zuarets
  • 839
  • 2
  • 10
  • 20