Saturday, August 10, 2019

Part 4 - How to implement custom Forms Authentication in ASP.NET MVC4 application

Step-1 : Add a class for extends IIdentity and Implement Go to solution explorer > Right click on the project name > Add > Class > Enter class name > Add.
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security.Principal;
  5. using System.Web;
  6.  
  7. namespace MvcAuthentication
  8. {
  9. public class MyIdentity : IIdentity
  10. {
  11. public IIdentity Identity { get; set; }
  12. public User User { get; set; }
  13.  
  14. public MyIdentity(User user)
  15. {
  16. Identity = new GenericIdentity(user.Username);
  17. User = user;
  18. }
  19.  
  20. public string AuthenticationType
  21. {
  22. get { return Identity.AuthenticationType; }
  23. }
  24.  
  25. public bool IsAuthenticated
  26. {
  27. get { return Identity.IsAuthenticated; }
  28. }
  29.  
  30. public string Name
  31. {
  32. get { return Identity.Name; }
  33. }
  34. }
  35. }

Step-2: Add a class for extends IPrincipal and Implement

Go to solution explorer > Right click on the project name > Add > Class > Enter class name > Add.
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security.Principal;
  5. using System.Web;
  6. using System.Web.Security;
  7.  
  8. namespace MvcAuthentication
  9. {
  10. public class MyPrincipal : IPrincipal
  11. {
  12. private readonly MyIdentity MyIdentity;
  13. public MyPrincipal(MyIdentity _myIdentity)
  14. {
  15. MyIdentity = _myIdentity;
  16. }
  17. public IIdentity Identity
  18. {
  19. get { return MyIdentity; }
  20. }
  21.  
  22. public bool IsInRole(string role)
  23. {
  24. return Roles.IsUserInRole(role);
  25. }
  26. }
  27. }

Step-3: Update Login POST Action code of MyAccountController (created in the part 1).

Here I have replaced the existing code
  1. [HttpPost]
  2. [ValidateAntiForgeryToken]
  3. public ActionResult Login(Login l, string ReturnUrl = "")
  4. {
  5.  
  6. // Here we will replace our existing code (what I have used in the previous part) used for clear understanding
  7. #region Existing Code
  8. //using (MyDatabaseEntities dc = new MyDatabaseEntities())
  9. //{
  10. // var user = dc.Users.Where(a => a.Username.Equals(l.Username) && a.Password.Equals(l.Password)).FirstOrDefault();
  11. // if (user != null)
  12. // {
  13. // FormsAuthentication.SetAuthCookie(user.Username, l.RememberMe);
  14. // if (Url.IsLocalUrl(ReturnUrl))
  15. // {
  16. // return Redirect(ReturnUrl);
  17. // }
  18. // else
  19. // {
  20. // return RedirectToAction("MyProfile", "Home");
  21. // }
  22. // }
  23. //}
  24. #endregion
  25. //Here I am going to use Membership provider to validate user
  26.  
  27. #region Part 2 Code
  28. //if (ModelState.IsValid)
  29. //{
  30. // var isValidUser = Membership.ValidateUser(l.Username, l.Password);
  31. // if (isValidUser)
  32. // {
  33. // FormsAuthentication.SetAuthCookie(l.Username, l.RememberMe);
  34. // if (Url.IsLocalUrl(ReturnUrl))
  35. // {
  36. // return Redirect(ReturnUrl);
  37. // }
  38. // else
  39. // {
  40. // return RedirectToAction("Index", "Home");
  41. // }
  42. // }
  43. //}
  44. #endregion
  45.  
  46. #region Part 4 Code
  47. if (ModelState.IsValid)
  48. {
  49. bool isValidUser = Membership.ValidateUser(l.Username, l.Password);
  50. if (isValidUser)
  51. {
  52. User user = null;
  53. using (MyDatabaseEntities dc = new MyDatabaseEntities())
  54. {
  55. user = dc.Users.Where(a => a.Username.Equals(l.Username)).FirstOrDefault();
  56. }
  57.  
  58. if (user != null)
  59. {
  60. JavaScriptSerializer js = new JavaScriptSerializer();
  61. string data = js.Serialize(user);
  62. FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.Username, DateTime.Now, DateTime.Now.AddMinutes(30), l.RememberMe, data);
  63. string encToken = FormsAuthentication.Encrypt(ticket);
  64. HttpCookie authoCookies = new HttpCookie(FormsAuthentication.FormsCookieName, encToken);
  65. Response.Cookies.Add(authoCookies);
  66. return Redirect(ReturnUrl);
  67. }
  68. }
  69. }
  70. #endregion
  71.  
  72. ModelState.Remove("Password");
  73. return View();
  74. }

Step-4: Add Application_PostAuthenticateRequest event in the Global.asax page

  1. protected void Application_PostAuthenticateRequest()
  2. {
  3. HttpCookie authoCookies = Request.Cookies[FormsAuthentication.FormsCookieName];
  4. if (authoCookies != null)
  5. {
  6. FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authoCookies.Value);
  7. JavaScriptSerializer js = new JavaScriptSerializer();
  8. User user = js.Deserialize<User>(ticket.UserData);
  9. MyIdentity myIdentity = new MyIdentity(user);
  10. MyPrincipal myPrincipal = new MyPrincipal(myIdentity);
  11. HttpContext.Current.User = myPrincipal;
  12. }
  13. }

Step-5: Edit Layout page for show additional data from HttpContext.Current.User

  1. <div style="text-align:right;">
  2. @{
  3. if (Request.IsAuthenticated)
  4. {
  5. var identity = (HttpContext.Current.User as MvcAuthentication.MyPrincipal).Identity as MvcAuthentication.MyIdentity;
  6. <text>@string.Format("Hello {0}", identity.User.EmailID)</text>
  7. }
  8. }
  9. </div>

Step-6: Run Application.

No comments:

Post a Comment

How to register multiple implementations of the same interface in Asp.Net Core?

 Problem: I have services that are derived from the same interface. public interface IService { } public class ServiceA : IService { ...