所以对asp.net mvc中的身份验证非常困惑 [英] So very very confused about Authentication in asp.net mvc
问题描述
我得出的结论是,我需要放弃ASP.NET Membership
(出于原因列表).
I come to the conclusion I need to ditch the ASP.NET Membership
(for list of reasons).
现在,我真正需要的唯一一件事就是创建一个cookie(由Form Authentication
完成),用于身份验证的自定义方法(完成)以及最终基于它们是否已登录或按角色进行验证.
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.
我被困在最后一个.
我正在尝试覆盖Authorize
(属性),但是我不知道如何执行此操作.我查看了许多示例,每个示例似乎都与下一个示例有所不同.我不知道他们为什么要这样做,或者我应该使用哪一个.
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.
有些教程似乎在AuthorizeCore
中进行身份验证,有些教程在OnAuthentication
中进行身份验证.
Some tutorials seem to do the authentication in the AuthorizeCore
, Some do it in the OnAuthentication
.
有些使用某些AuthorizationContext
东西,然后调用此基类.
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")]
参考文献:- http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ asp.net mvc添加到AUTHORIZE属性 http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx
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
修改
这就是我现在拥有的.
[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 */);
}
}
悬而未决的问题
- 为什么要密封?如果是密封的 它不会使单位更难吗 测试?
- 什么是filterContext?
- 为什么不使用AuthorizeCore?仅有的 OnAuthentication?
-
高速缓存指的是什么?喜欢 缓存角色吗?还是页面? 我不能告诉调试器 似乎每一个都运行代码 时间.
- 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.
缓存安全吗?
通常这样安全(即没有孔) 在其中被剥夺-有点担心 我会搞砸了,有 我网站上的一些主要漏洞).
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).
推荐答案
这是一个自定义属性,可以根据您的需要工作;为角色类型使用Enum并自己使用cookie创建,这允许存储角色.
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.
用法
[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中,并在基本控制器中将其读回.我的实现还有其他一些您可能不希望看到的细节,因此最好在这里阅读:
you'll need to have explicitly added your roles to auth cookie and read them back in a base controller say. 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
这篇关于所以对asp.net mvc中的身份验证非常困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!