Dotnet-Boxed/Framework

Boxed.AspNetCore.TagHelpers.SubresourceIntegrityTagHelper v5.1.0 - Blazor AspNetCore 5.0 - 5.0.203

Simonl9l opened this issue · 6 comments

Describe the bug

Have installed the Nuget package (5.1.0)

Im not sure I have things set up correctly but the articles don't seem to mention Blazor support specifically and any steps beyond adding the additional attributes to the <script> elements etc.

On inspection of the generated index.htm I see that the adding the script attributes per the articles seems to do noting.
Screen Shot 2021-05-28 at 1 10 58 PM

To Reproduce

A link to some code to reproduce the bug can speed up a fix. Alternatively, show steps to reproduce the behaviour:

  1. installed the Nuget Package
  2. Edited the _Host.cshtml as follows (excerpt):
 <environment exclude="Development">
        <link rel="stylesheet" href="<cdn URL to file>"
              asp-fallback-href="<local path to file>"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
              asp-subresource-integrity-src="<local path to file>"
              asp-subresource-integrity-hash-algorithms="SHA256 | SHA384 | SHA512"
              crossorigin="anonymous" />
      </environment>   
  1. Build Blazor App
  2. Connect browser and view page source (see image above)

Perhaps either the tag helps is doing nothing n this context (badly configured) or the Blazor code is not letting the tag helper run ?

Expected behavior

Have the SRI integrity has suitably generated, and assume it removes the asp-subresource-integrity-src and asp-subresource-integrity-hash-algorithms attributes and values.

I've not tested with Blazor. More information about how the subresource integrity tag helper works can be found at:

https://rehansaeed.com/subresource-integrity-taghelper-using-asp-net-core-part-2/

If there is something we need to do specifically for Blazor, I'd be willing to take a PR for it.

Hi @RehanSaeed thanks for the reply....

I have read both parts of you articles in detail. I'm not sure what's really needed for Blazor (Server) on DotNet 5. So no clue on any needs for a PR.

To this point, I've added the tag helper reference to the top fo the _Host.cshtlm file as follows:

@addTagHelper *, Boxed.AspNetCore.TagHelpers

I note that the setup such as this:

<link rel="stylesheet" href="<http path to host cdn for my_css_file>.css"
                  asp-fallback-href="<path to local my_css_file>.css"
                  asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                  asp-subresource-integrity-src="<path to local my_css_file>.css"
                  asp-subresource-integrity-hash-algorithms="SHA512" />

seems to do noting, is the <link> element supported ?

However, the following:

<script src="<http path to host cdn for my_js_file>.js"
                    asp-fallback-href="<path to local my_js_file>.js"
                    asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
                    asp-subresource-integrity-src="<path to local my_js_file>.js"
                    asp-subresource-integrity-hash-algorithms="SHA512"></script>

causes the following exception:

InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor' while attempting to activate 'Boxed.AspNetCore.TagHelpers.SrcSubresourceIntegrityTagHelper'.
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
lambda_method66(Closure , IServiceProvider , object[] )
Microsoft.AspNetCore.Mvc.Infrastructure.TypeActivatorCache.CreateInstance<TInstance>(IServiceProvider serviceProvider, Type implementationType)
Microsoft.AspNetCore.Mvc.Razor.Infrastructure.DefaultTagHelperActivator.Create<TTagHelper>(ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.DefaultTagHelperFactory.CreateTagHelper<TTagHelper>(ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorPageBase.CreateTagHelper<TTagHelper>()
<my server namespace>.Pages.Pages__Host+<>c__DisplayClass32_0+<<ExecuteAsync>b__8>d.MoveNext()
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
<my server namespace>.Pages.Pages__Host+<>c__DisplayClass32_0+<<ExecuteAsync>b__1>d.MoveNext() in _Host.cshtml
-
                <div class="content-center mt-4">
                    <button class="btn btn-outline-primary h4" onclick="location.reload()">Reload Page</button>
                </div>
            </div>
        </div>
        <app>
            @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
        </app>
        
        <environment include="Development">
            <script autostart="false" src="_framework/blazor.server.js"></script>
        </environment>
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
<my server namespace>.Pages.Pages__Host.ExecuteAsync() in _Host.cshtml
+
    }
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Specifically on the @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered)) line in _Host.cshtml

You need to register the IActionContextAccessor in IoC like so:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>()

@RehanSaeed thanks, that works for the <script> elements...is this Tag Helper also supported for css stylesheets via <link> elements?

All this also have an impact of the CSP, have you or any other users f th is library also tied in any CSP generation.

Asked and answered...

for links the attribute is asp-subresource-integrity-href
for scripts the attribute is asp-subresource-integrity-src

From multiple parses of the two articles I did not find this difference noted - and just tried a hunch.

Glad you found the answers. Regarding CSP, there shouldn't be any negative effect.