TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
Answers
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
Forums
Monthly Leaders
Forum guidelines
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.
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();
/// <summary>Retorna a página inicial de Register
/// <para>Utilizada para registro autônomo do usuário</para>
/// </summary>
//Registration Action
[HttpGet]
[AllowAnonymous]
public
ActionResult Register()
{
return
View();
}
/// <summary>Retorna a página com o formulário de registro autônomo
/// </summary>
//Registration POST action
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public
async Task<ActionResult> 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);
}
/// <summary>Retorna página de verificação de e-mail
/// </summary>
//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();
}
/// <summary>Retorna Página parcial responsável pelo login
/// </summary>
//Login
[HttpGet]
[AllowAnonymous]
public
ActionResult Login()
{
return
View();
}
/// <summary>Retorna a página com o formulário de login
/// </summary>
//Login POST
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public
async Task<ActionResult> 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();
}
/// <summary>Retorna a página de logout
/// </summary>
//Logout
[AuthorizedAction]
[HttpPost]
public
ActionResult Logout()
{
FormsAuthentication.SignOut();
return
RedirectToAction(
"Login"
,
"Conta"
);
}
/// <summary>Envia e-mail de confirmação de senha
/// </summary>
[NonAction]
private
async Task<string> 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;
}
/// <summary>Retorna a página de "esqueci minha senha"
/// </summary>
[AllowAnonymous]
public
ActionResult ForgotPassword()
{
return
View();
}
/// <summary>Envia e-mail para criação de nova senha
/// </summary>
[HttpPost]
[AllowAnonymous]
public
async Task<ActionResult> 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);
}
/// <summary>Retorna a página de confirmação de "esqueci minha senha"
/// </summary>
//GET: /Account/ForgotPasswordConfirmation
[AllowAnonymous]
public
ActionResult ForgotPasswordConfirmation()
{
return
View();
}
/// <summary>Retorna a página para reset de senha
/// </summary>
[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();
}
}
/// <summary>Retorna a página com o formulário para reset de senha
/// </summary>
[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);
}
/// <summary>Retorna a página de confirmação de reset de senha
/// </summary>
// GET: /Account/ResetPasswordConfirmation
[AllowAnonymous]
public
ActionResult ResetPasswordConfirmation()
{
return
View();
}
}
}
<globalization culture=
"pt-BR"
uiCulture=
"pt-BR"
enableClientBasedCulture=
"true"
/>
<customErrors mode=
"Off"
/>
<authentication mode=
"Forms"
>
<forms name=
".User"
cookieless=
"UseDeviceProfile"
loginUrl=
"~/Conta/Login"
path=
"/"
timeout=
"5760"
protection=
"All"
slidingExpiration=
"true"
></forms>
<!--<forms name=
".User"
cookieless=
"UseDeviceProfile"
loginUrl=
"~/Conta/Login"
domain=
"indicamais.com.br"
path=
"/"
timeout=
"5760"
></forms>-->
</authentication>
<sessionState sqlConnectionString=
"DefaultConnection"
mode=
"InProc"
sqlCommandTimeout=
"30"
/>
We also use a class to encrypt user passwords
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;
}
}
}
Reply
Answers (
0
)
C# Replace ComImport with standard referenced interface
Popup window with a search box and gridview