【问题标题】:MvcSiteMapNodeProvider with security trimming enabled throws sql exception启用安全修剪的 MvcSiteMapNodeProvider 引发 sql 异常
【发布时间】:2015-07-15 04:30:48
【问题描述】:

当我运行 MVC5 EF6 MSSQL 2012 应用程序时,我收到以下异常。

我将问题追踪到配置中的一行

<add key="MvcSiteMapProvider_SecurityTrimmingEnabled" value="true" />

删除此行后,我的网站就可以正常构建,但安全调整功能已关闭,因此现在我的菜单已损坏。

整个appSettings部分如下

<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="SkipApplicationAuthorizationRole" value="Developer" />
<add key="MvcSiteMapProvider_UseExternalDIContainer" value="false" />
<add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="false" />
<add key="MvcSiteMapProvider_IncludeAssembliesForScan" value="Triton.Web" />
<add key="MvcSiteMapProvider_SecurityTrimmingEnabled" value="true" />
<add key="MvcSiteMapProvider_AttributesToIgnore" value="type" />
<add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider" />
<add key="mvc" />
<add key="Twilio.Sid" value="PNf8944dec9bf751ad111f87e1a7ece2b3" />
<add key="Twilio.Token" value="2d1a16e5f7109c56307cc6b696ff1de4" />
<add key="Twilio.Phone" value="3362522181" />

关于如何解决此问题的任何想法?

编辑 我忘了提到,当连接字符串指向生产 SQL 服务器在本地运行时,这不是问题,但我仍然会提供我的 connection string

<add name="DefaultConnection" connectionString="Data Source=localhost;Initial Catalog=name; User ID=user;Password=password;Integrated Security=False;" providerName="System.Data.SqlClient" />

【问题讨论】:

    标签: sql-server asp.net-mvc entity-framework-6 mvcsitemapprovider


    【解决方案1】:

    将以下代码添加到我的 web.config 解决了我的问题。这会覆盖托管公司服务器上的其他配置文件以获取密钥。

    <membership>
      <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <profile>
      <providers>
        <clear />
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="false">
      <providers>
        <clear />
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>
    

    【讨论】:

      【解决方案2】:

      安全修整为 SiteMap 中的每个节点创建一个控制器实例。尽管它不与实体框架进行交互,但对甜甜圈的一个或多个控制器构造函数进行交互。

      要使用此功能,即使您实际上并未使用 DI,也必须遵循以 DI 为中心的控制器方法。换句话说,构造函数应该总是简单而轻量——它们应该只是分配依赖项(无论你是否可以将它们实际传递给构造函数)。请参阅this answer 了解解决构造函数问题的几种解决方案。

      另一种可能性是您有一个 AuthorizeAttribute 的自定义子类,它调用数据库。如果他们不需要确定用户是否被授权,您应该使用与 Microsoft 相同的处理程序来推迟这些调用。 MvcSiteMapProvider 不执行处理程序,但它执行确定用户是否被授权的逻辑。

      这是来自 MVC 5.2 的 AuthorizeAttribute 的 sn-p(通过 Reflector):

      /* Defer execution of result to a handler */
      protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
      {
          filterContext.Result = new HttpUnauthorizedResult();
      }
      
      public virtual void OnAuthorization(AuthorizationContext filterContext)
      {
          if (filterContext == null)
          {
              throw new ArgumentNullException("filterContext");
          }
          if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
          {
              throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
          }
          if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
          {
              if (this.AuthorizeCore(filterContext.HttpContext))
              {
                  HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
                  cache.SetProxyMaxAge(new TimeSpan(0L));
                  cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);
              }
              else
              {
                  this.HandleUnauthorizedRequest(filterContext);
              }
          }
      }
      

      【讨论】:

      • 我的意思是按照回答结束这个问题,但你的前两句话阐明了为什么我的 SQL 抛出异常。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 1970-01-01
      相关资源
      最近更新 更多