Wesley Henrique

Wesley Henrique

  • NA
  • 24
  • 658

Custom Authorise AuthorizeAttribute Does Not Update After Ba

Oct 2 2019 3:14 PM
Hi guys, I'm having a problem with my system authorization, I will give a quick explanation of how it works, my system is using FormsAuthentication to login, so it uses a custom AuthorizeAttribute where it user permissions on controllers and action,
This AuthorizeAttribute works so we have a Profile table and a menus table, so it gets more dynamic, but we noticed a problem when creating / editing a profile it keeps the old Authorization until the application is restarted in the visual or in the environment restart session.
 
  1. using Newtonsoft.Json;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Mvc;  
  7. using System.Web.Routing;  
  8.   
  9. namespace macpartner.Models.CustomAuthorise  
  10. {  
  11.     public  class AuthorizedAction : AuthorizeAttribute  
  12.     {  
  13.   
  14.         protected override bool AuthorizeCore(HttpContextBase httpContext)    
  15.         {  
  16.   
  17.             var isAuthorized = base.AuthorizeCore(httpContext);  
  18.             if (!isAuthorized)  
  19.             {  
  20.                 return false;  
  21.             }  
  22.   
  23.             var routeData = httpContext.Request.RequestContext.RouteData;  
  24.             string action = routeData.GetRequiredString("action");  
  25.             string controller = routeData.GetRequiredString("controller");  
  26.   
  27.             return MyCustomDbAccessLayer.IsUserAuthorized(httpContext.User.Identity.Name, action, controller);  
  28.         }  
  29.     }  
  30.   
  31.     public  class MyCustomDbAccessLayer : IDisposable  
  32.     {  
  33.         private static  MacPartnerContext db = new MacPartnerContext();  
  34.   
  35.         public static bool IsUserAuthorized(string username, string action, string controller)  
  36.         {  
  37.   
  38.             action = action.ToLowerInvariant();  
  39.             controller = controller.ToLowerInvariant();  
  40.   
  41.             var user = db.Users.Where(tp => tp.UserName == username).FirstOrDefault();  
  42.             if (user != null)  
  43.             {   
  44.                 var perfil = db.Perfils.Find(user.PerfilId);  
  45.   
  46.                 var acesso = perfil.MenusId.Where(c => c.Controller.ToLowerInvariant() == controller && c.Action.ToLowerInvariant() == action).FirstOrDefault();  
  47.   
  48.                 if (acesso != null)  
  49.                 {  
  50.                     return true;  
  51.   
  52.                 }  
  53.                 else  
  54.                 {  
  55.                     return false;  
  56.                 }  
  57.   
  58.             }  
  59.             else  
  60.             {  
  61.                 return false;  
  62.             }  
  63.              
  64.         }  
  65.   
  66.         public void Dispose()  
  67.         {  
  68.             db.Dispose();  
  69.         }  
  70.     }  
  71. }  
  1. using macpartner.Classes;  
  2. using macpartner.Helpers;  
  3. using macpartner.Models;  
  4. using macpartner.Models.CustomAuthorise;  
  5. using System;  
  6. using System.Collections.Generic;  
  7. using System.Linq;  
  8. using System.Threading.Tasks;  
  9. using System.Web;  
  10. using System.Web.Mvc;  
  11. using System.Web.Security;  
  12.   
  13. namespace macpartner.Controllers.MVC  
  14. {  
  15.     public class ContaController : Controller  
  16.     {  
  17.         private MacPartnerContext db = new MacPartnerContext();  
  18.   
  19.         /// <summary>Retorna a página inicial de Register  
  20.         /// <para>Utilizada para registro autônomo do usuário</para>  
  21.         /// </summary>  
  22.         //Registration Action  
  23.         [HttpGet]  
  24.         [AllowAnonymous]  
  25.         public ActionResult Register()  
  26.         {  
  27.             return View();  
  28.         }  
  29.   
  30.   
  31.         /// <summary>Retorna a página com o formulário de registro autônomo  
  32.         /// </summary>  
  33.         //Registration POST action   
  34.         [HttpPost]  
  35.         [AllowAnonymous]  
  36.         [ValidateAntiForgeryToken]  
  37.         public async Task<ActionResult> Register(User user)  
  38.         {  
  39.             //bool Status = false;  
  40.             string message = "";  
  41.   
  42.             user.ActivationCode = Guid.NewGuid();  
  43.             user.Password = Crypto.Encrypt(user.Password);  
  44.             user.ConfirmPassword = Crypto.Encrypt(user.ConfirmPassword);  
  45.             user.ConfirmarEmail = false;  
  46.             user.IsEnabled = true;  
  47.             user.PerfilId = db.Perfils.Where(p => p.Name.Equals("Parceiro")).FirstOrDefault().PerfilId;  
  48.             user.CampanhaId = db.Campanhas.Where(c => c.Tipo.Equals("Cashback")).FirstOrDefault().CampanhasId;  
  49.             if (ModelState.IsValid)  
  50.             {  
  51.                 var isExiste = UserHelper.EmailExiste(user.UserName);  
  52.                 if (isExiste)  
  53.                 {  
  54.                     ModelState.AddModelError("""");  
  55.                     ViewBag.Message = "Email já possui cadastro em nosso sistema";  
  56.                     return View(user);  
  57.                 }  
  58.   
  59.                 db.Users.Add(user);  
  60.                     await db.SaveChangesAsync();  
  61.                     string callbackUrl = await SendEmailConfirmationTokenAsync(user.UserName, "Por favor, confirme seu e-mail", Convert.ToString(user.ActivationCode));  
  62.                     ViewBag.Message = "Por favor, verifique seu e-mail antes de continuar.";  
  63.                     return View("Info");  
  64.   
  65.             }  
  66.             else  
  67.             {  
  68.                 message = "Erro na Requisição";  
  69.             }  
  70.   
  71.             ViewBag.Message = message;  
  72.             return View(user);  
  73.         }  
  74.   
  75.         /// <summary>Retorna página de verificação de e-mail  
  76.         /// </summary>  
  77.         //Verify Account    
  78.         [AllowAnonymous]  
  79.         [HttpGet]  
  80.         public ActionResult VerifyAccount(string id)  
  81.         {  
  82.             bool Status = false;  
  83.              
  84.             db.Configuration.ValidateOnSaveEnabled = false;  
  85.             var v = db.Users.Where(a => a.ActivationCode == new Guid(id)).FirstOrDefault();  
  86.             if (v != null)  
  87.             {  
  88.                 v.ConfirmarEmail = true;  
  89.                 db.SaveChanges();  
  90.                 Status = true;  
  91.             }  
  92.             else  
  93.             {  
  94.                 ViewBag.Message = "Requisição invalida";  
  95.             }  
  96.   
  97.             ViewBag.Status = Status;  
  98.             return View();  
  99.         }  
  100.   
  101.         /// <summary>Retorna Página parcial responsável pelo login  
  102.         /// </summary>  
  103.         //Login   
  104.         [HttpGet]  
  105.         [AllowAnonymous]  
  106.         public ActionResult Login()  
  107.         {  
  108.   
  109.             return View();  
  110.         }  
  111.   
  112.         /// <summary>Retorna a página com o formulário de login  
  113.         /// </summary>  
  114.         //Login POST  
  115.         [HttpPost]  
  116.         [AllowAnonymous]  
  117.         [ValidateAntiForgeryToken]  
  118.         public async Task<ActionResult> Login(UserLogin login, string ReturnUrl = "")  
  119.         {  
  120.             string message = "";  
  121.             var user = db.Users.Where(a => a.UserName == login.UserName).FirstOrDefault();  
  122.             if (user != null)  
  123.             {  
  124.   
  125.                 if (user.ConfirmarEmail == false)  
  126.                 {  
  127.                     Guid activationcode = user.ActivationCode;  
  128.                     string callbackUrl = await SendEmailConfirmationTokenAsync(user.UserName, "Confirmação de e-mail reenviada", activationcode.ToString());  
  129.                     ViewBag.Message = "Por favor, verifique seu e-mail antes de realizar o login.";  
  130.                     return View("Info");  
  131.   
  132.   
  133.                 }  
  134.                 else  
  135.                 {  
  136.                     if (user.IsEnabled == false)  
  137.                     {  
  138.                         return View("Lockout");  
  139.                     }  
  140.                     else  
  141.                     {  
  142.   
  143.                         if (string.Compare(Crypto.Encrypt(login.Password), user.Password) == 0)  
  144.                         {  
  145.   
  146.                             //int timeout = login.RememberMe ? 5760 : 20; // O usuario ficara salvo no cookie por 4 dias, caso contrario ficara 5 minutos c  
  147.                             //var ticket = new FormsAuthenticationTicket(login.UserName, login.RememberMe, timeout);  
  148.                             //string encrypted = FormsAuthentication.Encrypt(ticket);  
  149.                             //var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);  
  150.                             //cookie.Expires = DateTime.Now.AddMinutes(timeout);  
  151.                             //cookie.HttpOnly = true;  
  152.                             //Response.Cookies.Add(cookie);  
  153.   
  154.   
  155.                             FormsAuthentication.SetAuthCookie(login.UserName, login.RememberMe);  
  156.                            
  157.   
  158.                             if (Url.IsLocalUrl(ReturnUrl))  
  159.                             {  
  160.                                 return Redirect(ReturnUrl);  
  161.                             }  
  162.                             else  
  163.                             {  
  164.                                 return RedirectToAction("Index""Home");  
  165.                             }  
  166.                         }  
  167.                         else  
  168.                         {  
  169.                             message = " E-mail e / ou senha incorreto(s).";  
  170.                         }  
  171.                     }  
  172.                 }  
  173.             }  
  174.             else  
  175.             {  
  176.                 message = " E-mail e / ou senha incorreto(s).";  
  177.             }  
  178.   
  179.             ViewBag.Message = message;  
  180.             return View();  
  181.         }  
  182.   
  183.         /// <summary>Retorna a página de logout  
  184.         /// </summary>  
  185.         //Logout  
  186.         [AuthorizedAction]  
  187.         [HttpPost]  
  188.         public ActionResult Logout()  
  189.         {  
  190.             FormsAuthentication.SignOut();  
  191.             return RedirectToAction("Login""Conta");  
  192.         }  
  193.   
  194.         /// <summary>Envia e-mail de confirmação de senha  
  195.         /// </summary>  
  196.         [NonAction]  
  197.         private async Task<string> SendEmailConfirmationTokenAsync(string userName, string subject, string activationCode, string emailFor = "VerifyAccount")  
  198.         {  
  199.             var verifyUrl = "/Conta/" + emailFor + "/" + activationCode;  
  200.             var callbackUrl = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, verifyUrl);  
  201.   
  202.             if (emailFor == "VerifyAccount")  
  203.             {  
  204.                 string body = macpartner.Resources.emailConfirmationBody;  
  205.                 body = body.Replace("[link]", callbackUrl);  
  206.                 await MailHelper.SendMail(userName, subject, body);  
  207.             }  
  208.             if (emailFor == "ResetPassword")  
  209.             {  
  210.                 var body = macpartner.Resources.forgotPassBody;  
  211.                 body = body.Replace("Oi[nome]""Olá");  
  212.                 body = body.Replace("[link]", callbackUrl);  
  213.                 await MailHelper.SendMail(userName, subject, body);  
  214.             }  
  215.   
  216.             return callbackUrl;  
  217.         }  
  218.   
  219.         /// <summary>Retorna a página de "esqueci minha senha"  
  220.         /// </summary>  
  221.         [AllowAnonymous]  
  222.         public ActionResult ForgotPassword()  
  223.         {  
  224.             return View();  
  225.         }  
  226.   
  227.         /// <summary>Envia e-mail para criação de nova senha  
  228.         /// </summary>  
  229.         [HttpPost]  
  230.         [AllowAnonymous]  
  231.         public async Task<ActionResult> ForgotPassword(ForgotPasswordModel model)  
  232.         {  
  233.             var account = db.Users.Where(a => a.UserName == model.Email).FirstOrDefault();  
  234.             string message = "";  
  235.   
  236.             if (account != null)  
  237.             {  
  238.                 string resetCode = Guid.NewGuid().ToString();  
  239.                 await SendEmailConfirmationTokenAsync(account.UserName, "IndicaMais - Cadastro de Nova Senha", resetCode, "ResetPassword");  
  240.                 account.ResetPasswordCode = resetCode;  
  241.                 db.Configuration.ValidateOnSaveEnabled = false;  
  242.                 db.SaveChanges();  
  243.   
  244.                 return RedirectToAction("ForgotPasswordConfirmation""Conta");  
  245.             }  
  246.             else  
  247.             {  
  248.                 message = "Usuário Não encontrado";  
  249.             }  
  250.   
  251.             ViewBag.Message = message;  
  252.             return View(model);  
  253.         }  
  254.   
  255.         /// <summary>Retorna a página de confirmação de "esqueci minha senha"  
  256.         /// </summary>  
  257.         //GET: /Account/ForgotPasswordConfirmation  
  258.         [AllowAnonymous]  
  259.         public ActionResult ForgotPasswordConfirmation()  
  260.         {  
  261.             return View();  
  262.         }  
  263.   
  264.         /// <summary>Retorna a página para reset de senha  
  265.         /// </summary>  
  266.         [AllowAnonymous]  
  267.         public ActionResult ResetPassword(string id)  
  268.         {  
  269.   
  270.             if (string.IsNullOrWhiteSpace(id))  
  271.             {  
  272.                 return HttpNotFound("Error");  
  273.             }  
  274.   
  275.   
  276.             var user = db.Users.Where(a => a.ResetPasswordCode == id).FirstOrDefault();  
  277.             if (user != null)  
  278.             {  
  279.                 ResetPasswordModel model = new ResetPasswordModel();  
  280.                 model.ResetCode = id;  
  281.                 return View(model);  
  282.             }  
  283.             else  
  284.             {  
  285.                 return HttpNotFound();  
  286.             }  
  287.   
  288.         }  
  289.   
  290.         /// <summary>Retorna a página com o formulário para reset de senha  
  291.         /// </summary>  
  292.         [HttpPost]  
  293.         [AllowAnonymous]  
  294.         [ValidateAntiForgeryToken]  
  295.         public ActionResult ResetPassword(ResetPasswordModel model)  
  296.         {  
  297.             var message = "";  
  298.             if (ModelState.IsValid)  
  299.             {  
  300.   
  301.                 var user = db.Users.Where(a => a.ResetPasswordCode == model.ResetCode).FirstOrDefault();  
  302.                 if (user != null)  
  303.                 {  
  304.                     user.Password = Crypto.Encrypt(model.Password);  
  305.                     user.ConfirmPassword = Crypto.Encrypt(model.ConfirmPassword);  
  306.                     user.ResetPasswordCode = "";  
  307.                     db.Configuration.ValidateOnSaveEnabled = false;  
  308.                     db.SaveChanges();  
  309.                     return RedirectToAction("ResetPasswordConfirmation""Conta");  
  310.                 }  
  311.   
  312.             }  
  313.             else  
  314.             {  
  315.                 message = "Erro na requisição";  
  316.             }  
  317.             ViewBag.Message = message;  
  318.             return View(model);  
  319.         }  
  320.   
  321.         /// <summary>Retorna a página de confirmação de reset de senha  
  322.         /// </summary>  
  323.         // GET: /Account/ResetPasswordConfirmation  
  324.         [AllowAnonymous]  
  325.         public ActionResult ResetPasswordConfirmation()  
  326.         {  
  327.             return View();  
  328.         }  
  329.     }  
  330. }  
  1. <globalization culture="pt-BR" uiCulture="pt-BR" enableClientBasedCulture="true" />  
  2.   <customErrors mode="Off" />  
  3.   <authentication mode="Forms">  
  4.          <forms name=".User" cookieless="UseDeviceProfile" loginUrl="~/Conta/Login"  path="/" timeout="5760" protection="All" slidingExpiration="true"></forms>    
  5.     <!--<forms name=".User" cookieless="UseDeviceProfile" loginUrl="~/Conta/Login" domain="indicamais.com.br" path="/" timeout="5760"></forms>-->    
  6.   </authentication>  
  7.   <sessionState sqlConnectionString="DefaultConnection" mode="InProc" sqlCommandTimeout="30"/>  
 We also use a class to encrypt user passwords
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.IO;  
  4. using System.Linq;  
  5. using System.Security.Cryptography;  
  6. using System.Text;  
  7. using System.Web;  
  8.   
  9. namespace macpartner.Helpers  
  10. {  
  11.            public static class Crypto  
  12.         {  
  13.         public static string Encrypt(string password)  
  14.         {  
  15.   
  16.   
  17.             if (password == null)  
  18.             {  
  19.                 password = String.Empty;  
  20.             }  
  21.   
  22.               
  23.             var passwordBytes = Encoding.UTF8.GetBytes(password);  
  24.   
  25.         
  26.             passwordBytes = SHA256.Create().ComputeHash(passwordBytes);  
  27.   
  28.             var bytesEncrypted = Crypto.Encrypt(passwordBytes);  
  29.   
  30.             return Convert.ToBase64String(bytesEncrypted);  
  31.         }  
  32.   
  33.         
  34.         public static string Decrypt(string password)  
  35.         {  
  36.   
  37.             if (password == null)  
  38.             {  
  39.                 password = String.Empty;  
  40.             }  
  41.   
  42.               
  43.   
  44.             var passwordBytes = Encoding.UTF8.GetBytes(password);  
  45.   
  46.             passwordBytes = SHA256.Create().ComputeHash(passwordBytes);  
  47.   
  48.             var bytesDecrypted = Crypto.Decrypt(passwordBytes);  
  49.   
  50.             return Encoding.UTF8.GetString(bytesDecrypted);  
  51.         }  
  52.   
  53.         private static byte[] Encrypt(byte[] passwordBytes)  
  54.         {  
  55.             byte[] encryptedBytes = null;  
  56.   
  57.             
  58.             var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };  
  59.   
  60.             using (MemoryStream ms = new MemoryStream())  
  61.             {  
  62.                 using (RijndaelManaged AES = new RijndaelManaged())  
  63.                 {  
  64.                     var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);  
  65.   
  66.                     AES.KeySize = 256;  
  67.                     AES.BlockSize = 128;  
  68.                     AES.Key = key.GetBytes(AES.KeySize / 8);  
  69.                     AES.IV = key.GetBytes(AES.BlockSize / 8);  
  70.   
  71.                     AES.Mode = CipherMode.CBC;  
  72.   
  73.                     using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))  
  74.                     {  
  75.                         cs.Write(passwordBytes, 0, passwordBytes.Length);  
  76.                         cs.Close();  
  77.                     }  
  78.   
  79.                     encryptedBytes = ms.ToArray();  
  80.                 }  
  81.             }  
  82.   
  83.             return encryptedBytes;  
  84.         }  
  85.   
  86.         private static byte[] Decrypt(byte[] passwordBytes)  
  87.         {  
  88.             byte[] decryptedBytes = null;  
  89.   
  90.             var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };  
  91.   
  92.             using (MemoryStream ms = new MemoryStream())  
  93.             {  
  94.                 using (RijndaelManaged AES = new RijndaelManaged())  
  95.                 {  
  96.                     var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);  
  97.   
  98.                     AES.KeySize = 256;  
  99.                     AES.BlockSize = 128;  
  100.                     AES.Key = key.GetBytes(AES.KeySize / 8);  
  101.                     AES.IV = key.GetBytes(AES.BlockSize / 8);  
  102.                     AES.Mode = CipherMode.CBC;  
  103.   
  104.                     using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))  
  105.                     {  
  106.                         cs.Write(passwordBytes, 0, passwordBytes.Length);  
  107.   
  108.                     }  
  109.   
  110.                     decryptedBytes = ms.ToArray();  
  111.                 }  
  112.             }  
  113.   
  114.             return decryptedBytes;  
  115.         }  
  116.   
  117.     }  
  118. }