Custom user authorization based with roles in asp.net mvc
Solution 1
using the link shared by @VikasRana http://www.codeproject.com/Articles/578374/AplusBeginner-splusTutorialplusonplusCustomplusF
I got rid of my enum Role and my method
public CustomAuthorizeAttribute(params object[] roles)
{ ...}
I then changed Role in my model to be a string e.g. User.Role="Admin" instead of int. In my onAuthorization method I changed it to:
` public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Controller.TempData["ErrorDetails"] = "You must be logged in to access this page";
filterContext.Result = new RedirectResult("~/User/Login");
return;
}
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Controller.TempData["ErrorDetails"] = "You don't have access rights to this page";
filterContext.Result = new RedirectResult("~/User/Login");
return;
}
}
and in my global.asax added this.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (FormsAuthentication.CookiesSupported == true && Request.IsAuthenticated== true)
{
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
try
{
//let us take out the username now
string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
string roles = string.Empty;
using (GManagerDBEntities db = new GManagerDBEntities())
{
User user = db.Users.SingleOrDefault(u => u.Username == username);
roles = user.Role;
}
//let us extract the roles from our own custom cookie
//Let us set the Pricipal with our user specific details
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(
new System.Security.Principal.GenericIdentity(username, "Forms"), roles.Split(';'));
}
catch (Exception)
{
//something went wrong
}
}
}
}
Above method is not ideal though.It gets run for every simple page request about 3 times or more.
So here is solution 2:better solution Implement a custom role provider since we are already using custom role implementation.Simply follow this linkhttp://techbrij.com/custom-roleprovider-authorization-asp-net-mvc
Solution 2
Thanks Gotalove for this method in Global.asax. Here is some more help for anyone trying to do a custom Forms Authentication (FormsAuthentication, FormsAuthenticationTicket) using entity framework.
Login Controller SetAuthTicket
protected void GetRoles(int UserID)
{
var db = new ResearchSurveysEntities();
string[] getRoles = { };
try
{
var query =
from p in db.UserProfiles
join i in db.webpages_UsersInRoles on p.UserId equals i.UserId
join r in db.webpages_Roles on i.RoleId equals r.RoleId
where p.UserId == UserID
select new { p.UserId, r.RoleName };
if (query.Count() > 0)
{
List<string> gRoles = new List<string>();
foreach (var item in query)
{
gRoles.Add(item.RoleName);
}
getRoles = gRoles.ToArray();
}
roles = String.Join("|", getRoles);
}
catch (Exception ex)
{
WebUtilities wu = new WebUtilities();
wu.NotifyWebmaster(ex.ToString(), "Get roles for AdminUserID: " + UserID.ToString(), string.Empty, "Login Error");
}
finally
{
db.Dispose();
}
}
WebConfig
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Global.asax (From above example)
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
return;
FormsAuthenticationTicket authTicket;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
return;
}
// retrieve roles from UserData
string[] roles = authTicket.UserData.Split('|');
if (Context.User != null)
Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
GotaloveCode
PHP, VB.NET, C#, ASP.NET MVC, Sharepoint Developer, Office 365 MCSA
Updated on April 11, 2020Comments
-
GotaloveCode about 4 years
I have created a custom authentication and authorisation for my users.The problem I am facing is how to get mvc to check that role from inside my users table matches the [Authorize(Role)] on my controller so as to set httpauthorised to true.Below is my customauthorise class.
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class CustomAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.Controller.TempData["ErrorDetails"] = "You must be logged in to access this page"; filterContext.Result = new RedirectResult("~/User/Login"); return; } if (filterContext.HttpContext.Request.IsAuthenticated) { using (var db = new GManagerDBEntities()) { var authorizedRoles = (from u in db.Users where u.Username == filterContext.HttpContext.User.Identity.Name select u.Role).FirstOrDefault(); Roles = String.IsNullOrEmpty(Roles) ? authorizedRoles.ToString() : Roles; } } if (filterContext.Result is HttpUnauthorizedResult) { filterContext.Controller.TempData["ErrorDetails"] = "You do nat have necessary rights to access this page"; filterContext.Result = new RedirectResult("~/User/Login"); return; } } public CustomAuthorizeAttribute(params object[] roles) { if (roles.Any(r => r.GetType().BaseType != typeof(Enum))) throw new ArgumentException("roles"); this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r))); } }
below is my controller with decoration
[CustomAuthorize(Role.Administrator)] [HttpGet] public ActionResult CreateEmployees() { return View(); }
and my enum for role
public enum Role { Administrator = 1, UserWithPrivileges = 2, User = 3, }
and model
public class UserModel { public int UserID { get; set; } [Required] [Display(Name="Username:")] public string Username { get; set; } [Required] public string Password { get; set; } public int Role { get; set; } }
see pastie for clear view pastie
links I have viewed in trying to solve this among others but I cant seem to piece it togetherMVC 3 Authorize custom roles http://forums.asp.net/p/1573254/3948388.aspx