【发布时间】:2016-12-31 17:34:57
【问题描述】:
如何避免 Telerik KendoUI 在使用 ASP.NET MVC Kendo 组件时创建内联脚本?
避免内联脚本的原因是为了遵守 CSP 标头
Content-Security-Policy: script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com
而且不会出现类似的错误
拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com”。
有没有办法删除剑道生成的内联脚本或 将内容安全策略 nonce / sha256 附加到脚本?
简单示例(KendoUI 菜单)
cshtml
@(Html.Kendo().Menu()
.Name("nav-menu")
.Items(items =>
{
items.Add().Text("Home").Action("Index", "Overview");
})
)
浏览器html
<ul class="k-widget k-reset k-header k-menu k-menu-horizontal" id="nav-menu" data-role="menu" tabindex="0" role="menubar" aria-activedescendant="nav-menu_mn_active">
<li class="k-item k-state-highlight k-state-default k-first" role="menuitem">
<a class="k-link" href="/">Home</a>
</li>
</ul>
<script>
jQuery(function(){jQuery("#nav-menu").kendoMenu({});});
</script>
解决方案
在@dimodi 的回答之后,我最终在 kendo 延迟初始化脚本上使用了 nonce。
cshtml
@(Html.Kendo().Menu()
.Name("nav-menu")
.Items(items =>
{
items.Add().Text("Home").Action("Index", "Overview");
})
.Deferred()
)
<script type="text/javascript" nonce="@Html.ScriptNonce()">
@Html.Kendo().DeferredScripts(false)
</script>
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
var rng = new RNGCryptoServiceProvider();
var nonceBytes = new byte[32];
rng.GetBytes(nonceBytes);
var nonce = Convert.ToBase64String(nonceBytes);
context.Set("ScriptNonce", nonce);
context.Response.Headers.Add("Content-Security-Policy",
new[] {$"script-src 'self' 'unsafe-eval' https://kendo.cdn.telerik.com 'nonce-{nonce}';"
});
return next();
});
}
}
public static class NonceHelper
{
public static IHtmlString ScriptNonce(this HtmlHelper helper)
{
var owinContext = helper.ViewContext.HttpContext.GetOwinContext();
return new HtmlString(owinContext.Get<string>("ScriptNonce"));
}
}
【问题讨论】:
标签: javascript asp.net-mvc kendo-ui telerik content-security-policy