9

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)
        {
            //???
        }
    }
}
Dragonseer
  • 2,874
  • 7
  • 29
  • 42
  • 2
    perhaps you can check out the samples at https://github.com/rustd/AspnetIdentitySample/tree/master/AspnetIdentitySample – muratgu Oct 11 '13 at 21:30
  • I have indeed been learning from the sample to get as far as I have. However, the sample is in MVC and uses a redirect post login, which, to my current understanding, is not possible in a Web API because it's a REST operation. The sample, as far as I can tell from the version I have from a few days ago, doesn't cover Web API at all. – Dragonseer Oct 11 '13 at 21:35
  • 1
    pls see Darin's answer: http://stackoverflow.com/questions/11014953/asp-net-web-api-authentication?rq=1 – wal Oct 11 '13 at 22:20

2 Answers2

14

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?

Community
  • 1
  • 1
Hongye Sun
  • 3,868
  • 1
  • 25
  • 18
  • Hey Hongye, thanks for the great blog post about OWIN security. Any chance to see something about Facebook integration on mobile applications? In the comments you say that "The sample code is still under review and I will create a blog about it after it's released.": do you have any news? Thanks – s0nica Jan 22 '14 at 14:47
  • can OWIN authentication be added to an existing web app that is using DotNetOpenAuth? – JeeShen Lee May 15 '14 at 15:52
  • 1
    `Your answer` does not really answer the question....that one is for external logins. What about if we don't want to use external logins? – Serj Sagan Oct 06 '14 at 01:05
1

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.

Community
  • 1
  • 1
Dragonseer
  • 2,874
  • 7
  • 29
  • 42