alanjuden / MvcReportViewer

Custom Report Viewer control to replace MS Report Viewer on MVC projects (also works on .NET Core as a Report Viewer).
MIT License
173 stars 108 forks source link

NTLM Issue Windows Server 2016 #80

Open OrangeGoblin1973 opened 5 years ago

OrangeGoblin1973 commented 5 years ago

I am trying to connect to a remote server with SSRS2016 on it. From my location when I run the code I get the following error:

I have researched as much as I can, but do not understand the error, as it points to the rendered sections in the log???

System.Threading.Tasks.Task<TResult>.GetResultCore(bool waitCompletionNotification)
AlanJuden.MvcReportViewer.ReportServiceHelpers.GetReportParameters(ReportViewerModel model, bool forRendering)
AlanJuden.MvcReportViewer.ReportServiceHelpers.ExportReportToFormat(ReportViewerModel model, string format, Nullable<int> startPage, Nullable<int> endPage)
AlanJuden.MvcReportViewer.CoreHtmlHelpers.RenderReportViewer(IHtmlHelper helper, ReportViewerModel model, Nullable<int> startPage)
AspNetCore.Views_Report_ReportViewer.<ExecuteAsync>b__15_1() in ReportViewer.cshtml
-
                }
            }
    </script>
}
@section Content {
    @Html.RenderReportViewer(Model)
}
Microsoft.AspNetCore.Mvc.Razor.RazorPage.RenderSectionAsyncCore(string sectionName, bool required)
Microsoft.AspNetCore.Mvc.Razor.RazorPage.RenderSection(string name, bool required)
AspNetCore.Views_Shared__Layout.<ExecuteAsync>b__54_1() in _Layout.cshtml
+
        @RenderSection("Content", required: false)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
AspNetCore.Views_Shared__Layout.ExecuteAsync()
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.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter)
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(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync<TFilter, TFilterAsync>()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

The C# is:

public class ReportController : AlanJuden.MvcReportViewer.ReportController
    {
        public ActionResult MyReport(string namedParameter1, string namedParameter2)
        {
            var model = this.GetReportViewerModel(Request);
            model.ReportPath = "/Reports/FrontPage";           

            return View("ReportViewer", model);
        }

        protected override ICredentials NetworkCredentials
        {
            get
            {
                //Custom Domain authentication (be sure to pull the info from a config file)
                return new System.Net.NetworkCredential ("name", "password", "dom");

                //Default domain credentials (windows authentication)
               // return System.Net.CredentialCache.DefaultNetworkCredentials;
            }
        }

        protected override string ReportServerUrl
        {
            get
            {
                //You don't want to put the full API path here, just the path to the report server's ReportServer directory that it creates (you should be able to access this path from your browser: http://13.79.1.65/ReportServer/ReportExecution2010.asmx )
                return "http://remoteip/ReportServer/ReportExecution2005.asmx";
            }
        }
    }
alanjuden commented 5 years ago

@OrangeGoblin1973, first thing I notice is that your ReportServerUrl in your ReportController appears to be incrorrect.

I've included the original code from ReportServerUrl property as a reference:

//You don't want to put the full API path here, just the path to the report server's ReportServer directory that it creates (you should be able to access this path from your browser: https://YourReportServerUrl.com/ReportServer/ReportExecution2005.asmx )
                return "https://YourReportServerUrl.com/ReportServer";

You're doing exactly what I'm warning against in the comment. I would try by fixing that first and see if that resolves the issue for you.

I'm assuming you would want to change to: return "http://remoteip/ReportServer";

OrangeGoblin1973 commented 5 years ago

@alanjuden Thank you for your reply.

I opened your .NET version and using the settings as you suggest, it works perfectly using System.Net.NetworkCredential. When I then try it in the netcore2.1 application I am building, it won't work and I get the NTLM issue. I have adjusted settings in IIS, in the launch file as well and changed and fiddled with every security setting I can find. I must be missing some dependencies somehow which is preventing the negotiation to happen. I have tried both Network and Windows authentication.

If you have any pointers it will be great, as I am right out of ideas now.

TIA

Error received.

System.AggregateException: One or more errors occurred. (The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'.) ---> System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'.
   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass1_0.<CreateGenericTask>b__0(IAsyncResult asyncResult)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at AlanJuden.MvcReportViewer.ReportServiceHelpers.GetReportParameters(ReportViewerModel model, Boolean forRendering)
   at AlanJuden.MvcReportViewer.ReportServiceHelpers.ExportReportToFormat(ReportViewerModel model, String format, Nullable`1 startPage, Nullable`1 endPage)
   at AlanJuden.MvcReportViewer.CoreHtmlHelpers.RenderReportViewer(IHtmlHelper helper, ReportViewerModel model, Nullable`1 startPage)
   at AspNetCore.Views_Report_ReportViewer.<ExecuteAsync>b__15_1() in C:\Users\D\Dropbox\\MappingApplication\MappingApplication\Views\Report\ReportViewer.cshtml:line 133
   at Microsoft.AspNetCore.Mvc.Razor.RazorPage.RenderSectionAsyncCore(String sectionName, Boolean required)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPage.RenderSection(String name, Boolean required)
   at AspNetCore.Views_Shared__Layout.<ExecuteAsync>b__54_1() in C:\Users\D\Dropbox\\MappingApplication\MappingApplication\Views\Shared\_Layout.cshtml:line 55
   at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
   at AspNetCore.Views_Shared__Layout.ExecuteAsync()
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, String contentType, Nullable`1 statusCode)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
   at Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
---> (Inner Exception #0) System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'.
   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass1_0.<CreateGenericTask>b__0(IAsyncResult asyncResult)<---
alanjuden commented 5 years ago

@OrangeGoblin1973, have you tried overriding the ClientCredentialType in your ReportController.cs? It's defaulted to Windows and you appear to be getting an NTLM error. Try using this:

protected override HttpClientCredentialType ClientCredentialType => HttpClientCredentialType.Ntlm;

loganmarshall1 commented 4 years ago

Hi @alanjuden I can confirm add that override line to the controller successfully solved this same issue for me :)