我得出结论我需要抛弃ASP.NET Membership
(出于原因列表)。
现在我真正唯一需要的是创建一个cookie(由Form Authentication
完成),自定义身份验证方法(完成),最后根据它们是登录还是按角色进行验证。
我被困在最后一个。
我试图覆盖Authorize
(属性),但我不知道如何做到这一点。我看了很多例子,每个例子的表现与下一个不同。我不知道他们为什么要这样做,或者我应该使用哪一个。
有些教程似乎在AuthorizeCore
中进行了身份验证,有些人在OnAuthentication
中进行了身份验证。
有些人使用了一些AuthorizationContext
的东西,然后调用这个基类。
base.OnAuthorization(filterContext);
有些人似乎在其中进行缓存。
我想要的是内置的所有功能,但只是连接到我的自定义表。就像我将拥有自己的角色表一样。我需要告诉它在哪里然后拉进去。
此外,我不知道如何做到这一点或如何装饰这样的标签
[Authorize(Roles="test")]
参考文献: - http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ asp.net mvc Adding to the AUTHORIZE attribute http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx
修改
这就是我现在所拥有的。
[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 */);
}
}
突出问题
什么是缓存引用?喜欢 是缓存角色吗?还是页面? 我无法用调试器告诉它 似乎每一个都运行代码 时间。
缓存是否安全?
一般来说这是安全的(即没有洞 在它被表达 - 有点担心 我会把事搞砸了 我网站上的一个主要洞。)
答案 0 :(得分:2)
这是一个自定义属性,可以按照您的意愿运行;使用Enum作为角色类型并自己使用cookie创建,允许存储角色。
使用
[AuthorizeAttributeCustom(RoleRequired = GoodRoles.YourRoleTypeHere)]
属性代码:
//http://stackoverflow.com/questions/977071/redirecting-unauthorized-controller-in-asp-net-mvc/977112#977112
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class AuthorizeAttributeCustom : AuthorizeAttribute
{
/// <summary>
/// The name of the view to render on authorization failure. Default is "Error".
/// </summary>
public string ViewName { get; set; }
public ViewDataDictionary ViewDataDictionary { get; set; }
public DeniedAccessView DeniedAccessView { get; set; }
private GoodRoles roleRequired = GoodRoles.None;
public GoodRoles RoleRequired { get{ return roleRequired;} set{ roleRequired = value;} } // this may evolve into sets and intersections with an array but KISS
public AuthorizeAttributeCustom()
{
ViewName = "DeniedAccess";
DeniedAccessView = new DeniedAccessView
{
FriendlyName = "n/a",
Message = "You do not have sufficient privileges for this operation."
};
ViewDataDictionary = new ViewDataDictionary(DeniedAccessView);
}
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;
}
if (RoleRequired == GoodRoles.None || filterContext.HttpContext.User.IsInRole(RoleRequired.ToString()))
{
// is authenticated and is in the required role
SetCachePolicy(filterContext);
return;
}
filterContext.Result = new ViewResult { ViewName = ViewName, ViewData = ViewDataDictionary };
}
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 */);
}
}
你需要明确地将你的角色添加到auth cookie并在基本控制器中读回来说。我的实现有你可能不想要的其他细节,所以最好在这里阅读:http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html