我正在使用WindowsTokenRoleProvider来确定ASP.NET Web应用程序中的Active Directory组成员身份.
我的问题是性能不好,特别是当用户在很多组中时.例如,我在253(!)组中,并且WindowsTokenRoleProvider花费大约150秒来确定我所在的组.
我知道我可以使用缓存,这样就不会对用户的后续请求进行此操作,但显然在第一次访问时需要花费很长时间.
我有什么选择?我可以强制WindowsTokenRoleProvider只考虑某些群体吗?(我只对5感兴趣).
我正在尝试在MVC3应用程序中使用自定义角色提供程序.我已经使用Ninject让会员提供商工作正常,但似乎无法让角色提供者工作.成员资格提供程序不需要无参数构造函数,但角色提供程序不需要.这是一些代码片段:
Web.config文件
<membership>
<providers>
<clear/>
<add name="MyMembershipProvider" type="MyApp.Models.NHibernateMembershipProvider"
applicationName="myApp" />
</providers>
</membership>
<roleManager enabled="true">
<providers>
<add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
applicationName="myApp" />
</providers>
</roleManager>
Run Code Online (Sandbox Code Playgroud)
我有一个Ninject模块.
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
this.Bind<ISession>().ToMethod(
x => MyApp.MvcApplication.SessionFactoryData.GetCurrentSession());
// Respository
this.Bind<IUserRepository>().To<UserRepository>();
this.Bind<MembershipProvider>().To<NHibernateMembershipProvider>();
this.Bind<RoleProvider>().To<NHibernateRoleProvider>();
}
}
Run Code Online (Sandbox Code Playgroud)
自定义成员资格提供者
public class NHibernateMembershipProvider : MembershipProvider
{
private IUserRepository _repo;
public NHibernateMembershipProvider(IUserRepository repository)
{
_repo = repository;
}
...
Run Code Online (Sandbox Code Playgroud)
角色提供者
public class NHibernateRoleProvider : RoleProvider
{
private IUserRepository _repo;
public NHibernateRoleProvider(IUserRepository repository)
{
_repo = …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用asp.net mvc4进行授权,所以我尝试使用WebSecurity.
WebSecurity.InitializeDatabaseConnection("tradefairindia", "Users", "Id", "Username", false);
Run Code Online (Sandbox Code Playgroud)
我把它放到Global.asax中,这就是错误发生的地方,"无法找到默认角色提供程序".
在互联网上,我读到我必须将这行代码添加到我的web.config中<roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">.但由于之前的错误,我已经添加了它.
我该如何解决这个问题?
编辑:
当我改变它给defaultProvider="SimpleRoleProvider"它一个新的错误.它说
命名空间'WebMatrix'中不存在类型或命名空间名称'Data'(您是否缺少程序集引用?)
我们有一个ASP.NET MVC应用程序,我们已经开发了自己的自定义RoleProvider类.没有缓存,它将访问每个请求的数据存储 - 不好.我们可以找到唯一的缓存选项(在web.config中)通过存储在客户端机器上的cookie.我的两个问题是:
有没有人有替代路线?我明白在Session中缓存这些信息也不好?
基本上我想在某人不属于我的属性中列出的角色时显示友好消息.目前我的应用程序只是将用户吐回到登录屏幕.我已经阅读了几篇关于创建一个仅扩展[AuthorizeAttribute]的自定义属性的帖子,但我认为必须有一些开箱即用的东西才能做到这一点?
有人可以指出我在正确的方向,我需要看到没有它将用户发送到登录表格,而只是拍摄他们"未授权"的消息?
我的MVC应用程序在单个页面请求期间在多个位置使用用户角色.我的问题是默认的SqlRoleProvider是否在页面请求的生命周期中缓存当前用户的角色?
例如,我在Controller方法的属性中使用Roles:
[Authorize(Roles = "Admin")]
Run Code Online (Sandbox Code Playgroud)
和自定义代码
if (user.IsInRole(MembershipRole.Admin))
{
// Do something
}
else if (user.IsInRole(MembershipRole.Printer))
{
// Do something else
}
Run Code Online (Sandbox Code Playgroud)
如果角色提供程序不缓存角色,是编写从默认角色继承的自定义角色提供程序的最佳解决方案,并覆盖方法以获取角色一次并在请求持续时间内缓存它们?这可以通过Authorize属性和我自己的代码都将使用缓存的角色来完成吗?
(如果您想知道,我不想使用cacheRolesInCookie web.config选项来缓存cookie中的角色).
在此先感谢您的任何建议.
[编辑以包含Joe回答触发的详细信息]
我反编译了System.Web.Mvc.AuthorizeAttribute,AuthorizeCore方法为每个要检查的角色调用以下方法:
httpContext.User.IsInRole
Run Code Online (Sandbox Code Playgroud)
然后窥视System.Web.Security.RolePrincipal(这就是"User"在上面),下面的方法确实使用了用户角色的缓存副本(或者如果为空则填充缓存):
public string[] GetRoles()
public bool IsInRole(string role)
Run Code Online (Sandbox Code Playgroud)
缓存作为字段存储在User上,因此其生命周期是在请求期间.
方法使用以下方法查找角色:
Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name)
Run Code Online (Sandbox Code Playgroud)
因此将使用您为应用程序选择的任何角色提供程序(默认或自定义).
使用VS 2013,标准MVC模板和身份提供程序框架
用户已登录,我有:
//....
UserManager.AddToRole(User.Identity.GetUserId(), "Members"); # Line X
RedirectToAction("Index", "Members");
Run Code Online (Sandbox Code Playgroud)
会员控制员如下:
[Authorize(Roles="Members")]
public class MembersController : Controller
{
// GET: Members
public ActionResult Index()
{
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
执行第X行后,我可以确认用户已添加到表中dbo.AspNetUserRoles.但是,用户在到达成员控制器时未通过角色检查. User.IsInRole("Members")返回false.
如果用户注销然后再次登录,则将访问"成员"控制器,即User.IsInRole("Members")现在返回true.
有缓存吗?为何延误?我该如何克服它?
我也尝试将第X行的方法转换为异步方法并使用UserManager.AddToRoleAsync.同样的延迟效应仍然存在.
代码非常简单---问题是groupPath字符串中有一个无效字符(确切地说是'/').
我想要做的事情(至少作为一个停止差距)是跳过DirectoryEntries我无法获得cn - 无论为什么.
但是,当我运行此代码时,catch块不会运行,而是我得到:服务器无法运行.和未处理的System.Runtime.InteropServices.COMException.
为什么catch阻止不会捕获此异常.
try
{
using (DirectoryEntry groupBinding = new DirectoryEntry("LDAP://" + groupPath))
{
using (DirectorySearcher groupSearch = new DirectorySearcher(groupBinding))
{
using (DirectoryEntry groupEntry = groupSearch.FindOne().GetDirectoryEntry())
{
results.Add(string.Format("{0}", groupEntry.Properties["cn"].Value.ToString()));
}
}
}
}
catch
{
Logger.Error("User has bad roles");
}
Run Code Online (Sandbox Code Playgroud)
附加观察:代码实际上是在一个自定义的RoleProvider中,好奇的是,如果我在一个简单的winforms应用程序中引用这个提供程序,并使用相同的输入调用这个相同的方法,那么catch块就会完全按照它的设想执行.我认为这表明有关.NET异常与COM异常的建议答案并不准确.虽然我无法理解为什么从WebDev服务器执行时此代码无法捕获
我正在开发一个将使用Windows角色提供程序的项目,我想限制某些AD组的功能.
使用MVC,我可以使用AuthorizeAttribute上面的操作方法并相应地重定向.对于不使用MVC的标准Web表单应用程序(.NET 3.5),我能做些类似的事情吗?
我已经和ASP.net MVC合作了好几年了.我过去开发的大多数应用程序都是通过旧版Web应用程序的链接访问的.当用户到达我的某个应用程序时,我的应用程序只是从浏览器中读取一个cookie,表明该用户已通过遗留应用程序进行了身份验证.
现在,我终于开发了一个全新的Web应用程序,需要能够执行身份验证和授权.我确信我可以做点工作,但我想知道今天最好的做法是什么.
从ASP.net WebForms,我熟悉MembershipProvider和RoleProvider类.我对Windows Identity Foundatioin(WIF)也有一点熟悉.
但是,当我查看默认的ASP.net MVC 4应用程序时,"AccountController"类使用称为WebSecurity类的东西.我想知道这是否意味着折旧MembershipProvider和RoleProvider类.
这应该是基本设置,具有由另一个服务器提供的用户名/密码身份验证以及对特权资源的基于角色的访问.
今天在ASP.net MVC 4中实现这些的最佳实践是什么?
.net security roleprovider membership-provider asp.net-mvc-4
roleprovider ×10
asp.net-mvc ×4
.net ×3
asp.net ×3
c# ×1
caching ×1
ninject ×1
performance ×1
roles ×1
security ×1
webforms ×1