Announcing RTM of ASP.NET Identity 2.1.0

Announcing RTM of ASP.NET Identity 2.1.0

  • Comments 13

We are releasing RTM of ASP.NET Identity 2.1.0. The main focus in this release was to fix bugs and add SignInManager to make it easier to use security features such as Account Lockout, Two-Factor Authentication for login.

ASP.NET Identity 2.1 is included in the ASP.NET templates which were released with VS 2013 Update 3. The templates have been updated to include Two-Factor Authentication.

Download this release

You can download ASP.NET Identity from the NuGet gallery. You can install or update these packages using the NuGet Package Manager Console, like this:

Install-Package Microsoft.AspNet.Identity.EntityFramework –Version 2.1.0 

Install-Package Microsoft.AspNet.Identity.Core -Version 2.1.0

Install-Package Microsoft.AspNet.Identity.OWIN -Version 2.1.0

What’s in this release?

Following is the list of features and major issues that were fixed in 2.1.0.

SignInManager

SignInManager makes it easier to add Two-Factor authentication, account lockout and other features when you login.

SignInManager was in the samples package in ASP.NET Identity 2.0. In version 2.1, we have added it in the framework

The following tutorials cover account confirmation and Two-Factor Authentication (including account lockout and protecting against brute force attacks against the two factor authentication codes)

http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity

http://www.asp.net/identity/overview/features-api/two-factor-authentication-using-sms-and-email-with-aspnet-identity

Following show the login code of an application which uses two-factor authentication and account lockout.

logincode

List of bugs fixed

You can look at all the bugs that were fixed in this release by clicking here.

Enable Two-Factor Authentication in ASP.NET templates using VS 2013 Update 3

The following steps summarize the experience of enabling Two-Factor Authentication using SMS in ASP.NET MVC. You can follow the same steps for other templates such as Web Forms as well. You can also write your own Two-Factor authentication provider (such as using QR codes using authenticator apps) and plug it in.

For a more detailed walkthrough of the code and the concepts refer to the following article http://www.asp.net/identity/overview/features-api/two-factor-authentication-using-sms-and-email-with-aspnet-identity

  • Create ASP.NET MVC Template and select Authentication using Individual User Accounts
  • Open Views\Manage\Index.cshtml and “Add Phone Number option” by uncommenting the following lines
    Code Snippet
    1. <dt>Phone Number:</dt>
    2.         <dd>
    3.             @(Model.PhoneNumber ?? "None") [
    4.             @if (Model.PhoneNumber != null)
    5.             {
    6.                 @Html.ActionLink("Change", "AddPhoneNumber")
    7.                 @: &nbsp;|&nbsp;
    8.                 @Html.ActionLink("Remove", "RemovePhoneNumber")
    9.             }
    10.             else
    11.             {
    12.                 @Html.ActionLink("Add", "AddPhoneNumber")
    13.             }
    14.             ]
    15.         </dd>

 

  • Open Views\Manage\Index.cshtml and enableTwo-Factor Authentication
  • Code Snippet
    1. <dt>Two-Factor Authentication:</dt>
    2.         <dd>
    3.             @if (Model.TwoFactor)
    4.             {
    5.                 using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    6.                 {
    7.                     @Html.AntiForgeryToken()
    8.                     <text>Enabled
    9.                         <input type="submit" value="Disable" class="btn btn-link" />
    10.                     </text>
    11.                 }
    12.             }
    13.             else
    14.             {
    15.                 using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    16.                 {
    17.                     @Html.AntiForgeryToken()
    18.                     <text>Disabled
    19.                         <input type="submit" value="Enable" class="btn btn-link" />
    20.                     </text>
    21.                 }
    22.             }
    23.         </dd>

  • Register a SMS provider in App_Start\IdentityConfig.cs
    • You can use any SMS services such as Twilio or others. For more information on using Twilio see this post. Your SMS service should look like as follows.

Code Snippet
  1. public class SmsService : IIdentityMessageService
  2. {
  3.     public Task SendAsync(IdentityMessage message)
  4.     {
  5.         var Twilio = new TwilioRestClient(Keys.TwilioSid, Keys.TwilioToken);
  6.         var result = Twilio.SendMessage(Keys.FromPhone, message.Destination, message.Body);
  7.  
  8.         // Twilio doesn't currently have an async API, so return success.
  9.         return Task.FromResult(0);
  10.     }
  11. }

  • Register a user
    • Browse to the site and register as a new user.

  • Go to Manage page: Click your username after logging in and go to Manage page. Here is what the Manage page would look like once you login

Manage

  • Add a Phone Number and verify it
    • You need to add a verified phone number before you can use it to get text messages for two-factor authentication.

phoneNumberAdded

  • Enable Two-Factor Authentication
    • Click on the “Two-Factor Authentication” to enable it.

Enable2FA

  • Logout and Login using username and password
    • When you login you will be prompted to select the Two-Factor authentication provider to use to get the code. You can choose between Email, SMS and you can also write your own Two-Factor authentication providers such as QR code generators using Authenticator apps.

send2facode

  • Get the code you got through SMS and verify it

RememberBrowser

  • Check the Remember the Two-Factor Authentication Option
    • Clicking on the this checkbox will exempt you from needing to use 2FA to log on with that computer and browser. You can do this on any private machine you regularly use. By setting Remember this browser, you get the added security of 2FA from computers you don't regularly use, and you get the convenience on not having to go through 2FA on your own computers.

  • Account Lockout
    • If you enter the code incorrectly then the account will be locked out for 5min after 5 incorrect tries. You will be able to login after 5 min without requiring an Admin action.

AccountLockout

 

    • Account Lockout feature in ASP.NET Identity can be configured inside the ApplicationUserManager in App_Start\IdentityConfig.cs as follows.
    • Code Snippet
      1. // Configure user lockout defaults
      2. manager.UserLockoutEnabledByDefault = true;
      3. manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
      4. manager.MaxFailedAccessAttemptsBeforeLockout = 5;

 

    • When you enter the two-factor verification code, the VerifyCode action uses the SignInManager to complete the two-factor SignIn process and protects for brute force attacks against the two factor codes.
      Code Snippet
      1. //
      2.         // POST: /Account/VerifyCode
      3.         [HttpPost]
      4.         [AllowAnonymous]
      5.         [ValidateAntiForgeryToken]
      6.         public async Task<ActionResult> VerifyCode(VerifyCodeViewModel model)
      7.         {
      8.             if (!ModelState.IsValid)
      9.             {
      10.                 return View(model);
      11.             }
      12.  
      13.             // The following code protects for brute force attacks against the two factor codes.
      14.             // If a user enters incorrect codes for a specified amount of time then the user account
      15.             // will be locked out for a specified amount of time.
      16.             // You can configure the account lockout settings in IdentityConfig
      17.             var result = await SignInManager.TwoFactorSignInAsync(
      18.                 model.Provider, model.Code, isPersistent:  model.RememberMe,
      19.                 rememberBrowser: model.RememberBrowser);
      20.             switch (result)
      21.             {
      22.                 case SignInStatus.Success:
      23.                     return RedirectToLocal(model.ReturnUrl);
      24.                 case SignInStatus.LockedOut:
      25.                     return View("Lockout");
      26.                 case SignInStatus.Failure:
      27.                 default:
      28.                     ModelState.AddModelError("", "Invalid code.");
      29.                     return View(model);
      30.             }
      31.         }
         

Samples/ Documentation

Migrating from ASP.NET Identity 2.0.0

This is a compatible release with 2.0.0 and there are no database schema changes with this release.

Give feedback and get support

    • If you find any bugs please open them at our Codeplex Site where we track all our bugs https://aspnetidentity.codeplex.com/
    • If you want to discuss these features or have questions, please discuss them on Stack Overflow and use the following tag “asp.net-identity”

The ASP.NET Identity team would like to thank you for trying out this release and your feedback for ASP.NET Identity.

Leave a Comment
  • Please add 4 and 1 and type the answer here:
  • Post
  • Any word about when the code will be open-sourced? Decompilers produce horrible code with all the asyncs involved, but having a source code makes it much-much easier to track down the issues and produce optimal solutions.

  • We do not have a timeline but we are working on it.

  • I have update this version of identity in my application and after update while i am adding user to role it is inserting null value in IdentityUser_Id column in userRoles table. Please let me know that is any code changes also need to do or it is a bug?

  • @Ashwini Rajpurohit: Can you provide the code you are  using to add the user to the role?

  • I am also having the same issue as @Ashwini Rajpurohit!

    Here's my code:

    public class AccountController : ApiController

       {

           private DbContext db;

           private UserManager<ApplicationUser> manager;

           public AccountController()

           {

               db = new DbContext();

               manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));

           }

    ...

    }

    and then the code I am using to Add a user to the Role:

    manager.AddToRole(applicationUser.Id, "Admin");

    My IdentityUserRole table has the following columns:

    RoleId

    UserId

    ApplicationUser_Id

    IdentityRole_Id

    Not sure why it was like this.  

    Does anyone know how to fix it?

  • @Anwit Pashar: Can you use IdentityDbContext instead of DbContext and see if it works fine. The additional field in UserRole reflect incorrect mapping between models and database

  • I am getting role1 and role2 as user selection during registration and after confirmation of email, i am adding him to respective role,it was working fine with previous version

    my approach is database first basically it is inserting null value in IdentityUser_Id column

    public async Task<ActionResult> ConfirmEmail(string userId, string code)

           {

               if (userId == null || code == null)

               {

                   return View("Error");

               }

               IdentityResult result = await UserManager.ConfirmEmailAsync(userId, code);

               if (result.Succeeded)

               {

                   SUsers user = db.SUsers.Find(userId);

                   var rolesForUser = UserManager.GetRoles(user.Id);

                   if(user.IsRole1)

                   {

                       if(!rolesForUser.Contains("Role1"))

                       {

                        result = UserManager.AddToRole(userId, "Role1");

                       }

                   }

                   if (user.IsRole2)

                   {

                       if (!rolesForUser.Contains("Role2"))

                       {

                           result = UserManager.AddToRole(userId, "Role2");

                       }

                   }

                   return View("ConfirmEmail");

               }

               else

               {

                   return View("Error");

               }

           }

  • HI all,

    I'm having the same issue as well. After upgrading to 2.1 if I regenerate the database (Add-Migration Initial and Update-Database) FK columns on the tables that map the many to many relationship between Users and Roles are inserted as NULL.

    Lost the whole day trying to understand what's wrong, but without much luck. I'm using code first and everything was working fine with 2.0.

    Any news on this yet?

    Thanks in advance,

    Stefano

  • @Pranav, I need to have authentication for normal users and administrators in my application, however, normal users should register and log in using their email address or via Facebook login, and administrators should only be able to register using a username.

    How can I do this? Should I keep different tables in my database for each kind of user?

  • One more thing I forgot to mention. I'm not using Entity Framework. My data access is made using Dapper micro-orm.

  • @pranav rastogi: I have noticed that source symbols for Identity are available on MS symbols server now. This is ace! Thank you for these!

  • Hi all,

    having the same disturbing issue with NULL values on IdentityRole_Id & IdentityUser_Id after upgrading to 2.1.0 from 2.0.0

    this is a major problem since i cannot add/edit roles to users.

    Any help here ?

    Thank's

    Eyal

  • @Eval, can you please open an issue on aspnetidentity.codeplex.com/ and provide steps on how are you seeing this issue.

Page 1 of 1 (13 items)