Hi
I come to the conclusion I need to ditch the ASP.NET Membership
(for list of reasons).
Now really the only thing I see that I need is creating a cookie(done by Form Authentication
), custom methods for authentication (done) and finally validation based on if they are logged in or by role.
I am stuck on the last one.
I am trying to override the Authorize
(attribute) but I have no clue how to do this. I looked at many examples and each one seems to be done differently then the next. I don't know why they do this or which one I should be using.
Some tutorials seem to do the authentication in the AuthorizeCore
, Some do it in the OnAuthentication
.
Some use some AuthorizationContext
thing and then call this base class.
base.OnAuthorization(filterContext);
Some seem to do caching in it.
What I want is all the functionality the built in ones have but just hooked up to my custom tables. Like I going to have my own Role table. I need to tell it where that is and pull the stuff in.
Also I have no clue how to do this or how decorate the tag like this
[Authorize(Roles="test")]
References:- http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ http://stackoverflow.com/questions/554094/asp-net-mvc-adding-to-the-authorize-attribute http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx
Edit
This is what I have now.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class AuthorizeAttributeCustom : AuthorizeAttribute
{
public string Roles { get; set; }
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
return;
}
DataClasses1DataContext test = new DataClasses1DataContext();
var name = filterContext.HttpContext.User.Identity.Name;
var user = test.User2s.Where(u => u.userName == name).FirstOrDefault();
var role = test.Roles.Where(u => u.UserId == user.userId).Select(u => u.Role1).FirstOrDefault();
string[] split = Roles.Split(',');
if (split.Contains(role) == true)
{
// is authenticated and is in the required role
SetCachePolicy(filterContext);
return;
}
filterContext.Result = new HttpUnauthorizedResult();
}
private void SetCachePolicy(AuthorizationContext filterContext)
{
// ** IMPORTANT **
// Since we're performing authorization at the action level, the authorization code runs
// after the output caching module. In the worst case this could allow an authorized user
// to cause the page to be cached, then an unauthorized user would later be served the
// cached page. We work around this by telling proxies not to cache the sensitive page,
// then we hook our custom authorization code into the caching mechanism so that we have
// the final say on whether a page should be served from the cache.
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
}
Out Standing Questions
- Why is it sealed? If it is sealed does it not make it harder to unit test?
- What is filterContext?
- Why is no AuthorizeCore used? Only OnAuthentication?
Whats the cache refering to? Like is it caching the role? Or the Page? I can't tell with the debugger it seems to run the code every single time.
Is caching it safe?
In general is this safe(ie no holes in it to be explioted- kinda worried I will screw something up and have some major hole in my site).