c# - SignalR 似乎正在使用 Windows 身份验证而不是使用匿名身份验证

标签 c# asp.net-mvc authorization signalr iis-10

我有一个使用 IIS 10 并启用了 Windows 身份验证和匿名身份验证的 Web 应用程序。该应用程序使用 SignalR 2.4.0 和 SQL 依赖项每十秒循环一次图像,用户可以使用设备停止循环并在返回循环之前按照自己的节奏显示演示文稿。 我遇到的问题是大多数应用程序需要使用 Windows 身份验证,并且一些 Controller 需要允许匿名访问。但是,匿名用户(例如智能电视或未加入域的机器)在未先进行身份验证的情况下无法显示图像。

我可能误解了情况,但我相信这是因为 signalR 使用的是 Windows 身份验证。如果我关闭要求输入用户名和密码的对话框,Microsoft Edge 的控制台将显示以下消息

HTTP401: DENIED - 请求的资源需要用户身份验证。 (XHR)GET - http://MyWebsite/Home/signalr/negotiate?clientProtocol=2.0&connectionData=%5B%7B%22name%22%3A%22signalrhub%22%7D%5D&_=1557410422010

我尝试过的大部分代码更改都在 web.config 中。主 web.config 文件有认证模式

<authentication mode="Windows" />

不过,我还有一个版本 web.config,其中包含允许显示 Controller 和信号器匿名的设置

<location path="Area/Controller" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
    <system.web>
      <authorization>
        <allow users="?" />
      </authorization>
    </system.web>
  </location>
  <location path="signalr" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
    <system.web>
      <authorization>
        <allow users="?" />
      </authorization>
    </system.web>
  </location>

我的第一个想法是我需要为位置路径添加一个通配符,这样它看起来像

<location path="signalr/*" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">

<location path="signalr/negotiate*" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">

但是通过四处搜索和测试似乎不接受它。

我也尝试过明确允许对路径进行匿名身份验证,但在到达身份验证阶段之前我收到错误 500

<location path="Area/Controller" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
    <system.webServer>
      <security>
        <authentication>
          <anonymousAuthentication enabled="true" />
        </authentication>
      </security>
    </system.webServer>
  </location>
  <location path="signalr" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
    <system.webServer>
      <security>
        <authentication>
          <anonymousAuthentication enabled="true" />
        </authentication>
      </security>
    </system.webServer>
  </location>

我还设置了 Controller 允许匿名

[AllowAnonymous]
 public class Controller
{
}

运行 signalR 脚本的 PartialView 在点击 connection.hub.start 时要求进行身份验证

<input type="hidden" name="connectionId" id="connectionId" />

<div id="divImageViewer"></div>

@Scripts.Render("~/bundles/jquery_signalR")

<script src="@Model.SignalRHubsUrl" type="text/javascript"></script>

@Html.HiddenFor(model => Model.MyModel.ModelItem)

<script type="text/javascript">
    $(function () {
        setTimeout(function () {
            $.connection.hub.start()
                .done(function () {
                    console.log("starting..."); //doesn't display in the console
                    var cid = $.connection.hub.id;
                    $("#connectionId").val(cid);
                    console.log("connected! Id: " + cid);
                    //do stuff
                })
                .fail(function (reason) {
                    console.log("SignalR connection failed: " + reason); //does display in the console after closing the dialog box
                });
    }, 5000); // Start connection after 5 seconds.
}

</script>

最终,我希望为大多数 Web 应用程序保留 Windows 身份验证,但仍允许对一些小部分进行匿名访问。

如果其中大部分都是无用的胡言乱语,我也很抱歉,其中很多对我来说仍然是新的,尤其是 javascript 和 jquery。

最佳答案

在获得一些帮助后设法将范围缩小到下面注释掉的行。一旦删除,SignalR 就可以毫无问题地匿名通过。

[assembly: OwinStartupAttribute(typeof(Go.Startup))]
namespace MyName
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var container = CompositionRoot.Compose();
            var controllerFactory = new InjectableControllerFactory(container);
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
            MvcSiteMapProviderConfig.Register(container);

            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
            app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

            //GlobalHost.HubPipeline.RequireAuthentication(); <---------

            app.MapSignalR(new HubConfiguration
            {
                EnableJSONP = true,
                EnableJavaScriptProxies = true,
                EnableDetailedErrors = true
            });

        }
    }
}

关于c# - SignalR 似乎正在使用 Windows 身份验证而不是使用匿名身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56062694/

相关文章:

ruby-on-rails - 存在 CanCan 问题的 Rails 授权

reactjs - ReactJS 和 .NET Core API 中的 windows 授权

WCF 安全 - 如何允许所有调用者访问此 url?

c# - 我无法在 .net 4.7 项目中使用 System.Runtime 4.3.0

c# - Caliburn 微 : DialogResult

c# - 如何隐藏窗口窗体中的所有面板?

asp.net-mvc - MVC-Ajax.BeginForm提供htmlfile:未知的运行时错误

c# - 从 App.xaml.cs 关闭 WPF 应用程序

c# - 如何从 ASP.NET MVC 中的 HttpModule 执行 Controller 操作?

c# - 使用 Json 将具有两个对象的 View 模型传递给 Controller