启用了安全修整的MvcSiteMapNodeProvider会抛出sql异常

时间:2015-07-15 04:30:49

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

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

excetption

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

<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" />

2 个答案:

答案 0 :(得分:0)

将以下代码添加到我的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>

答案 1 :(得分:0)

安全修整为SiteMap中的每个节点创建一个控制器实例。虽然它不与实体框架交互,但是对于一个或多个控制器构造函数的甜甜圈来说也是如此。

要使用此功能,即使您实际上没有使用DI,也必须遵循以DI为中心的控制器方法。换句话说,构造函数应该总是简单明了 - 它们除了分配依赖项之外什么都不做(无论你是否可以将它们实际传递给构造函数)。有关解决构造函数问题的几种解决方案,请参阅this answer

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

以下是MVC 5.2的AuthorizeAttribute片段(通过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);
        }
    }
}