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.
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Routing;
- namespace macpartner.Models.CustomAuthorise
- {
- public class AuthorizedAction : AuthorizeAttribute
- {
- protected override bool AuthorizeCore(HttpContextBase httpContext)
- {
- var isAuthorized = base.AuthorizeCore(httpContext);
- if (!isAuthorized)
- {
- return false;
- }
- var routeData = httpContext.Request.RequestContext.RouteData;
- string action = routeData.GetRequiredString("action");
- string controller = routeData.GetRequiredString("controller");
- return MyCustomDbAccessLayer.IsUserAuthorized(httpContext.User.Identity.Name, action, controller);
- }
- }
- public class MyCustomDbAccessLayer : IDisposable
- {
- private static MacPartnerContext db = new MacPartnerContext();
- public static bool IsUserAuthorized(string username, string action, string controller)
- {
- action = action.ToLowerInvariant();
- controller = controller.ToLowerInvariant();
- var user = db.Users.Where(tp => tp.UserName == username).FirstOrDefault();
- if (user != null)
- {
- var perfil = db.Perfils.Find(user.PerfilId);
- var acesso = perfil.MenusId.Where(c => c.Controller.ToLowerInvariant() == controller && c.Action.ToLowerInvariant() == action).FirstOrDefault();
- if (acesso != null)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
- public void Dispose()
- {
- db.Dispose();
- }
- }
- }
- using macpartner.Classes;
- using macpartner.Helpers;
- using macpartner.Models;
- using macpartner.Models.CustomAuthorise;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Security;
- namespace macpartner.Controllers.MVC
- {
- public class ContaController : Controller
- {
- private MacPartnerContext db = new MacPartnerContext();
- ///
Retorna a página inicial de Register - ///
Utilizada para registro autônomo do usuário - ///
- //Registration Action
- [HttpGet]
- [AllowAnonymous]
- public ActionResult Register()
- {
- return View();
- }
- ///
Retorna a página com o formulário de registro autônomo - ///
- //Registration POST action
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task
Register(User user) - {
- //bool Status = false;
- string message = "";
- user.ActivationCode = Guid.NewGuid();
- user.Password = Crypto.Encrypt(user.Password);
- user.ConfirmPassword = Crypto.Encrypt(user.ConfirmPassword);
- user.ConfirmarEmail = false;
- user.IsEnabled = true;
- user.PerfilId = db.Perfils.Where(p => p.Name.Equals("Parceiro")).FirstOrDefault().PerfilId;
- user.CampanhaId = db.Campanhas.Where(c => c.Tipo.Equals("Cashback")).FirstOrDefault().CampanhasId;
- if (ModelState.IsValid)
- {
- var isExiste = UserHelper.EmailExiste(user.UserName);
- if (isExiste)
- {
- ModelState.AddModelError("", "");
- ViewBag.Message = "Email já possui cadastro em nosso sistema";
- return View(user);
- }
- db.Users.Add(user);
- await db.SaveChangesAsync();
- string callbackUrl = await SendEmailConfirmationTokenAsync(user.UserName, "Por favor, confirme seu e-mail", Convert.ToString(user.ActivationCode));
- ViewBag.Message = "Por favor, verifique seu e-mail antes de continuar.";
- return View("Info");
- }
- else
- {
- message = "Erro na Requisição";
- }
- ViewBag.Message = message;
- return View(user);
- }
- ///
Retorna página de verificação de e-mail - ///
- //Verify Account
- [AllowAnonymous]
- [HttpGet]
- public ActionResult VerifyAccount(string id)
- {
- bool Status = false;
- db.Configuration.ValidateOnSaveEnabled = false;
- var v = db.Users.Where(a => a.ActivationCode == new Guid(id)).FirstOrDefault();
- if (v != null)
- {
- v.ConfirmarEmail = true;
- db.SaveChanges();
- Status = true;
- }
- else
- {
- ViewBag.Message = "Requisição invalida";
- }
- ViewBag.Status = Status;
- return View();
- }
- ///
Retorna Página parcial responsável pelo login - ///
- //Login
- [HttpGet]
- [AllowAnonymous]
- public ActionResult Login()
- {
- return View();
- }
- ///
Retorna a página com o formulário de login - ///
- //Login POST
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task
Login(UserLogin login, string ReturnUrl = "") - {
- string message = "";
- var user = db.Users.Where(a => a.UserName == login.UserName).FirstOrDefault();
- if (user != null)
- {
- if (user.ConfirmarEmail == false)
- {
- Guid activationcode = user.ActivationCode;
- string callbackUrl = await SendEmailConfirmationTokenAsync(user.UserName, "Confirmação de e-mail reenviada", activationcode.ToString());
- ViewBag.Message = "Por favor, verifique seu e-mail antes de realizar o login.";
- return View("Info");
- }
- else
- {
- if (user.IsEnabled == false)
- {
- return View("Lockout");
- }
- else
- {
- if (string.Compare(Crypto.Encrypt(login.Password), user.Password) == 0)
- {
- //int timeout = login.RememberMe ? 5760 : 20; // O usuario ficara salvo no cookie por 4 dias, caso contrario ficara 5 minutos c
- //var ticket = new FormsAuthenticationTicket(login.UserName, login.RememberMe, timeout);
- //string encrypted = FormsAuthentication.Encrypt(ticket);
- //var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
- //cookie.Expires = DateTime.Now.AddMinutes(timeout);
- //cookie.HttpOnly = true;
- //Response.Cookies.Add(cookie);
- FormsAuthentication.SetAuthCookie(login.UserName, login.RememberMe);
- if (Url.IsLocalUrl(ReturnUrl))
- {
- return Redirect(ReturnUrl);
- }
- else
- {
- return RedirectToAction("Index", "Home");
- }
- }
- else
- {
- message = " E-mail e / ou senha incorreto(s).";
- }
- }
- }
- }
- else
- {
- message = " E-mail e / ou senha incorreto(s).";
- }
- ViewBag.Message = message;
- return View();
- }
- ///
Retorna a página de logout - ///
- //Logout
- [AuthorizedAction]
- [HttpPost]
- public ActionResult Logout()
- {
- FormsAuthentication.SignOut();
- return RedirectToAction("Login", "Conta");
- }
- ///
Envia e-mail de confirmação de senha - ///
- [NonAction]
- private async Task
SendEmailConfirmationTokenAsync(string userName, string subject, string activationCode, string emailFor = "VerifyAccount") - {
- var verifyUrl = "/Conta/" + emailFor + "/" + activationCode;
- var callbackUrl = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, verifyUrl);
- if (emailFor == "VerifyAccount")
- {
- string body = macpartner.Resources.emailConfirmationBody;
- body = body.Replace("[link]", callbackUrl);
- await MailHelper.SendMail(userName, subject, body);
- }
- if (emailFor == "ResetPassword")
- {
- var body = macpartner.Resources.forgotPassBody;
- body = body.Replace("Oi[nome]", "Olá");
- body = body.Replace("[link]", callbackUrl);
- await MailHelper.SendMail(userName, subject, body);
- }
- return callbackUrl;
- }
- ///
Retorna a página de "esqueci minha senha" - ///
- [AllowAnonymous]
- public ActionResult ForgotPassword()
- {
- return View();
- }
- ///
Envia e-mail para criação de nova senha - ///
- [HttpPost]
- [AllowAnonymous]
- public async Task
ForgotPassword(ForgotPasswordModel model) - {
- var account = db.Users.Where(a => a.UserName == model.Email).FirstOrDefault();
- string message = "";
- if (account != null)
- {
- string resetCode = Guid.NewGuid().ToString();
- await SendEmailConfirmationTokenAsync(account.UserName, "IndicaMais - Cadastro de Nova Senha", resetCode, "ResetPassword");
- account.ResetPasswordCode = resetCode;
- db.Configuration.ValidateOnSaveEnabled = false;
- db.SaveChanges();
- return RedirectToAction("ForgotPasswordConfirmation", "Conta");
- }
- else
- {
- message = "Usuário Não encontrado";
- }
- ViewBag.Message = message;
- return View(model);
- }
- ///
Retorna a página de confirmação de "esqueci minha senha" - ///
- //GET: /Account/ForgotPasswordConfirmation
- [AllowAnonymous]
- public ActionResult ForgotPasswordConfirmation()
- {
- return View();
- }
- ///
Retorna a página para reset de senha - ///
- [AllowAnonymous]
- public ActionResult ResetPassword(string id)
- {
- if (string.IsNullOrWhiteSpace(id))
- {
- return HttpNotFound("Error");
- }
- var user = db.Users.Where(a => a.ResetPasswordCode == id).FirstOrDefault();
- if (user != null)
- {
- ResetPasswordModel model = new ResetPasswordModel();
- model.ResetCode = id;
- return View(model);
- }
- else
- {
- return HttpNotFound();
- }
- }
- ///
Retorna a página com o formulário para reset de senha - ///
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public ActionResult ResetPassword(ResetPasswordModel model)
- {
- var message = "";
- if (ModelState.IsValid)
- {
- var user = db.Users.Where(a => a.ResetPasswordCode == model.ResetCode).FirstOrDefault();
- if (user != null)
- {
- user.Password = Crypto.Encrypt(model.Password);
- user.ConfirmPassword = Crypto.Encrypt(model.ConfirmPassword);
- user.ResetPasswordCode = "";
- db.Configuration.ValidateOnSaveEnabled = false;
- db.SaveChanges();
- return RedirectToAction("ResetPasswordConfirmation", "Conta");
- }
- }
- else
- {
- message = "Erro na requisição";
- }
- ViewBag.Message = message;
- return View(model);
- }
- ///
Retorna a página de confirmação de reset de senha - ///
- // GET: /Account/ResetPasswordConfirmation
- [AllowAnonymous]
- public ActionResult ResetPasswordConfirmation()
- {
- return View();
- }
- }
- }
"pt-BR" uiCulture="pt-BR" enableClientBasedCulture="true" /> -
"Off" /> -
"Forms" > -
".User" cookieless="UseDeviceProfile" loginUrl="~/Conta/Login" path="/" timeout="5760" protection="All" slidingExpiration="true"> -
"DefaultConnection" mode="InProc" sqlCommandTimeout="30"/>
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Security.Cryptography;
- using System.Text;
- using System.Web;
- namespace macpartner.Helpers
- {
- public static class Crypto
- {
- public static string Encrypt(string password)
- {
- if (password == null)
- {
- password = String.Empty;
- }
- var passwordBytes = Encoding.UTF8.GetBytes(password);
- passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
- var bytesEncrypted = Crypto.Encrypt(passwordBytes);
- return Convert.ToBase64String(bytesEncrypted);
- }
- public static string Decrypt(string password)
- {
- if (password == null)
- {
- password = String.Empty;
- }
- var passwordBytes = Encoding.UTF8.GetBytes(password);
- passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
- var bytesDecrypted = Crypto.Decrypt(passwordBytes);
- return Encoding.UTF8.GetString(bytesDecrypted);
- }
- private static byte[] Encrypt(byte[] passwordBytes)
- {
- byte[] encryptedBytes = null;
- var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
- using (MemoryStream ms = new MemoryStream())
- {
- using (RijndaelManaged AES = new RijndaelManaged())
- {
- var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
- AES.KeySize = 256;
- AES.BlockSize = 128;
- AES.Key = key.GetBytes(AES.KeySize / 8);
- AES.IV = key.GetBytes(AES.BlockSize / 8);
- AES.Mode = CipherMode.CBC;
- using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
- {
- cs.Write(passwordBytes, 0, passwordBytes.Length);
- cs.Close();
- }
- encryptedBytes = ms.ToArray();
- }
- }
- return encryptedBytes;
- }
- private static byte[] Decrypt(byte[] passwordBytes)
- {
- byte[] decryptedBytes = null;
- var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
- using (MemoryStream ms = new MemoryStream())
- {
- using (RijndaelManaged AES = new RijndaelManaged())
- {
- var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
- AES.KeySize = 256;
- AES.BlockSize = 128;
- AES.Key = key.GetBytes(AES.KeySize / 8);
- AES.IV = key.GetBytes(AES.BlockSize / 8);
- AES.Mode = CipherMode.CBC;
- using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
- {
- cs.Write(passwordBytes, 0, passwordBytes.Length);
- }
- decryptedBytes = ms.ToArray();
- }
- }
- return decryptedBytes;
- }
- }
- }
Replies
Know the answer? Post it — somebody with the same question will find it here.