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

3
  • If that is WebAPI project - check IdentityConfig in app_start and StartUp.cs Commented Aug 4, 2015 at 12:39
  • It is a webAPI project, check for what? Commented Aug 4, 2015 at 13:38
  • What you set in context, what is your ApplicationManager, and check what you use in your controller. I will can write in few hours, if you will still need help Commented Aug 4, 2015 at 14:07

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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.
My DB has been created by an MVC 3 schema
OK, it seems, my DB schema is simple membership, how do I change the provider?
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.