我有一个MVC4应用程序,我使用自定义角色提供程序为我的用户分配了角色,这样当我在User表中检查User.IsInRole时,它确定在我的_Layout.cshtml页面中显示哪些链接等。这正在布局页面上,因为正在显示正确的链接。
然而,当我使用
保护我的Admin控制器时[Authorize(Roles = "Admin")]
我从未设置为对象错误实例的对象获取以下堆栈跟踪:
[NullReferenceException: Object reference not set to an instance of an object.]
System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) +39
System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) +159
System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +96
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +446
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +382
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
此过滤器上下文到底是什么?当我使用基于ADFS或基于表单的身份验证但在使用基于Windows的身份验证时,我必须执行以下操作才能使IsInRole方法正常工作:
this.UserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
if (this.UserName.Contains("\\"))
{
string[] stringArray = this.UserName.Split(new Char[] { '\\' });
this.UserName = stringArray[1];
MyUser identity = userRepository.Get(u => u.Username == this.UserName).FirstOrDefault();
HttpContext.Current.User = identity;
}
我是否需要正确配置其他一些HttpContext才能使Authorize属性与IsInRole方法一样工作?
答案 0 :(得分:0)
在表单的情况下,它可能是任何东西,但是在用户表中使用用户名查找用户名密码表单是非常常见的,基于所呈现的代码,它看起来像存储库只需要一个用户名,它只是事实证明,windows.identity.name返回domain \ user。这是分配到域,用户的额外努力的地方。以下示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication6
{
public class DemoAuthAttribute : AuthorizeAttribute
{
// create a file like auth.cs in the mvc project
// called
// [DemoAuth("BAR")]
// as an attibute on a controller method
private string _role;
public DemoAuthAttribute(string role)
{
_role = role; // should be exapanded to handle more than one
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return httpContext.Request.IsAuthenticated && _role == "FOO";
// lookup the current user in database does the user have role as specificed by the attribute?
// if yes sucess if not fail.
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (AuthorizeCore(filterContext.HttpContext))
{
// your custom logic here
string text = string.Format("<u><h5>Auth successfull.....</h5></u></br>");
filterContext.HttpContext.Response.Write(text);
}
else
{
// RedirectResult, etc.
string text = string.Format("<u><h5>Auth unsuccessfull.....</h5></u></br>");
filterContext.HttpContext.Response.Write(text);
}
}
}
}