0

Я использую MvcSitemapProvider для моего проекта ASP MVC 5.MvcSitemapProvider throwing Исключение переполнения при использовании currentNode

Я внедрил пользовательскую авторизацию, чтобы проверить, соответствуют ли роли из карты сайта ролям пользователей.

Это то, что он выглядит следующим образом:

public class CustomAuthorize : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool authorize = false; 

     var roles = SiteMaps.Current.CurrentNode.Roles; 
     foreach (var role in roles) 
      if (System.Web.Security.Roles.IsUserInRole(role)) 
       authorize = true; 

     return authorize; 
    } 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new HttpUnauthorizedResult(); 
    } 
} 

Моя проблема заключается в том, что при использовании SiteMaps.Current.CurrentNode.Roles он бросает An unhandled exception of type 'System.StackOverflowException' occurred in System.Web.dll, и я понятия не имею, почему. Объекты заполнены, ничто не равно нулю.

Почему это происходит? Сейчас я не знаю, как заставить это работать как простой currentNode, не работает ...

+0

Когда вы отлаживаете, он получает доступ к каждому циклу или является ли исключение перед этим? – Casey

+0

Он вызывается методом currentNode, который является методом mvcsitemapprovider. Вот почему я не знаю, что делать, потому что я не могу повлиять на нее и не знаю, почему она брошена. – Rovdjuret

ответ

1

Реализация по умолчанию AuthorizeAttribute - это все, что вам нужно для взаимодействия с MvcSiteMapProvider. AuthorizeAttribute уже поддерживает роли.

// Only users in the "Manager" role have access to all actions on this controller 
[Authorize(Roles = "Manager")] 
public class AccountController : Controller 
{ 
    public ActionResult Manage() 
    { 
     return View(); 
    } 

    public ActionResult ChangePassword() 
    { 
     return View(); 
    } 
} 

Единственное, что вам нужно сделать, это включить обрезку безопасности. См. Документацию security trimming.

+0

Спасибо за отзыв. Я знаю, что могу использовать его, как вы советуете, но я хотел бы, чтобы он зависел от файла Sitemap, потому что я хочу изменить его во время выполнения. Контроллеры компилируются и не могут меняться ... Вот почему я хочу получить роли sitemap на текущем узле и проверить, есть ли у пользователя эти роли. Есть ли другой способ? – Rovdjuret

+1

Вы не можете использовать коллекцию ролей для этой цели. SiteMap кэшируется и используется для всех пользователей, и динамически невозможно динамически изменять роли во время выполнения. Вы должны искать другой способ определить это динамическое поведение, но вы используете правильный подход, подклассифицируя AuthorizeAttribute, поэтому его нужно определять только в одном месте. Посмотрите на претензии MVC 5. – NightOwl888

1

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

Я бы сохранил роли, которые вы хотите проверить по-другому.

+0

Скорее всего! Думаю, мне придется использовать модуль acl и пропустить пользовательский атрибут. – Rovdjuret