1

У меня есть приложение MVC4, в котором я назначил роли моему пользователю с помощью настраиваемого поставщика роли, поэтому, когда я проверяю User.IsInRole на мою таблицу User, он определяет, какие ссылки и т. Д. Отображаться на экране на моей странице _Layout.cshtml. Это работает на странице «Макет», в которой появляются правильные ссылки.Атрибут авторизации, не работающий с приложением Windows Authentication

Однако, когда я защитить мой контроллер администратора с помощью

[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; 
} 

Мне нужно настроить некоторые другие Do HttpContext надлежащее в чтобы атрибут Authorize работал так же, как метод IsInRole?

+0

Кто-нибудь может мне помочь с этим? 50 очков теперь доступно спасибо – Jay

+0

Можете ли вы установить точку останова только до того, как получите это. Имя пользователя? Я предполагаю, что GetCurrent() возвращает null. FilterContext предоставит вам все, что вам нужно, чтобы написать свой фильтр, который будет включать в себя httpcontext и словарь маршрута. Посмотрите http://msdn.microsoft.com/en-us/library/dd381609(v=vs.100).aspx для разных контекстов фильтров. –

+0

GetCurrent возвращает имя пользователя, и я правильно могу получить имя пользователя, однако из этого контекста авторизации и текущего пользовательского контекста не устанавливается так, как это сделано в ADFS и Forms, все, что требовалось, это получить имя пользователя, которое я могу сделать здесь, я догадываюсь, что мне не хватает шага – Jay

ответ

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); 
     } 
    } 

} 

}

+0

Я получил имя пользователя отдельно и разделил часть домена, чтобы получить только имя пользователя, и это работает для метода .IsInRole, но не в методе Authorize. Я думаю, что это связано с тем, что не существует настраиваемого контекста авторизации, и мне интересно, как я могу это сделать, чтобы текущий пользователь был связан с поставщиком настраиваемых ролей таким же образом, как при аутентификации через ADFS и формы – Jay

+0

ok I Понимаю. это пользовательский поставщик, который вы написали, или thirdparty/open source? –

+0

Его тот, который я написал, работает для пользователей, прошедших проверку подлинности ADFS и Forms. Я просто не уверен, как получить контекст авторизации для пользователя, основываясь на том, как я устанавливаю HttpContext.Current.User, который хорошо работает для User.IsInRole – Jay

Смежные вопросы