[英]So very very confused about Authentication in asp.net mvc
I come to the conclusion I need to ditch the ASP.NET Membership
(for list of reasons). 我得出结论我需要抛弃ASP.NET
Membership
(出于原因列表)。
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. 现在我真正唯一需要的是创建一个cookie(由
Form Authentication
完成),自定义Form Authentication
方法(完成),最后根据他们是登录还是按角色进行验证。
I am stuck on the last one. 我被困在最后一个。
I am trying to override the Authorize
(attribute) but I have no clue how to do this. 我试图覆盖
Authorize
(属性),但我不知道如何做到这一点。 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
. 有些教程似乎在
AuthorizeCore
进行身份验证,有些教程在OnAuthentication
。
Some use some AuthorizationContext
thing and then call this base class. 有些人使用一些
AuthorizationContext
,然后调用这个基类。
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/ asp.net mvc Adding to the AUTHORIZE attribute http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx 参考文献: - http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ asp.net mvc添加到AUTHORIZE属性 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 突出问题
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). 一般情况下这是安全的(即没有漏洞可以说明 - 有点担心我会搞砸一些东西并在我的网站上有一些重要的漏洞)。
Here's a custom attribute that would work just as you want it; 这是一个自定义属性,可以按照您的需要工作; using an Enum for role types and using cookie creation yourself, which allows for storing of roles.
使用Enum作为角色类型并自己使用cookie创建,允许存储角色。
usage 用法
[AuthorizeAttributeCustom(RoleRequired = GoodRoles.YourRoleTypeHere)]
attribute code: 属性代码:
//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 */);
}
}
you'll need to have explicitly added your roles to auth cookie and read them back in a base controller say. 你需要明确地将你的角色添加到auth cookie并在基本控制器中读回来说。 my implementation has other details which you might not want so maybe best to read here: http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html
我的实现有你可能不想要的其他细节,所以最好在这里阅读: http : //ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.