Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Identity in a Web API

I am working on a simple application that uses the new ASP.NET Identity for authentication. Since I plan to have a mobile app in the future, I have placed the authentication in a Web API, which I post to from jQuery from a Razor Web Page (no MVC or Forms). So far, post works fine and creates users and logs them in - on the API side.

However, I am unable to determine how to proceed from there. I need to set IsAuthenticated so that I can serve up the right pages but it always returns false. Since Identity is extremely new, there is very little documentation available for it and I am unable to locate anything as complex as running it from a Web API.

Q: What is the correct way to return from Identity authentication in a Web API after logging in so that User.Identity.IsAuthenticated gets set correctly?

Login.cshtml

@if (User.Identity.IsAuthenticated)
{
    @RenderPage("/userpage.cshtml");
}

else
{
    <form id="loginForm">
        <b>Login</b>
        <input type="email" placeholder="Email" name="email" id="loginEmail" />
        <input type="password" placeholder="Password" name="password" id="loginPassword" />
        <input type="submit" value="Log In"/>
    </form>
 }

<script>
    $("#loginForm").submit(function(event)
    {
        event.preventDefault();
        $.post("/api/login/",
        {
            Username: $('#loginEmail').val(),
            Password: $('#loginPassword').val()
        }, function () 
           { 
               //???
           }, "json");

        return false;
    });
</script>

Login Web API

public class LoginController : ApiController
{
    public async void Post(UserInfo info)
    {
        var manager = new AuthenticationIdentityManager(new IdentityStore());
        var result = await manager.Authentication.CheckPasswordAndSignInAsync(HttpContext.Current.GetOwinContext().Authentication, info.Username, info.Password, true);

        if (result.Success)
        {
            //???
        }
    }
}
like image 456
Dragonseer Avatar asked Oct 11 '13 19:10

Dragonseer


2 Answers

It depends on what authentication method you are using. Most of the web applications use Form (Cookie) authentication module as primary authentication method. It should work fine with your web pages, but it isn't the best choice if you want to work with your API on the native client like a mobile app. You should be careful with CSRF attack when enabling cookie authentication with web api.

Supposing that you are using cookie authentication, you still have two choices. One is FormsAuthentication IIS module, which is quite old, you should use FormsAuthentication.SetAuthCookie to sign in the user.

The other way is OWIN cookie middleware, which is used in default MVC 5 template to support authentication. Please check my answer on how to sign in user by OWIN API

If you want to have a better authentication story for web API with mobile app, I will suggest you to use the OWIN OAuth middleware to enable bearer token as primary authentication method for web api. In MVC 5 SPA template, it demonstrates a good pattern to use them together along with MVC and cookie auth. My blog Understanding Security Features in the SPA Template for VS2013 RC should give a general idea on how they are working together.

The identity framework has an OWIN package which implements most of the OWIN authentication code. So you don't need to implement your own. Why not use it?

like image 69
Hongye Sun Avatar answered Oct 10 '22 20:10

Hongye Sun


Building off of Hongye Sun's answer, the correct method is to use OWIN cookie middleware to transfer and store cookies. The correct way to accomplish this is by adding a Startup.cs to the project root and with the following content (this is avaliable in the start up templates offered in VS). The Web API response will automatically send over the cookie.

using Microsoft.AspNet.Identity.Owin;
[assembly: OwinStartup(typeof(MyApp.Startup))]
namespace MyApp
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseSignInCookies();
        }
    }
}

See Hongye Sun's answer to this question for a full explanation with more details, including external authentication.

like image 24
Dragonseer Avatar answered Oct 10 '22 20:10

Dragonseer