Анонимный доступ к SignalR-хабу с сервером идентификации 4 - PullRequest
1 голос
/ 02 октября 2019

Мне не удается получить доступ к моей конечной точке SignalR (из javascript) при использовании IdentityServer4.

Установка сервера идентификации 4, установка + сигнализатор. К сожалению, я не понимаю полностью вывод журнала.

CORS request made for path: /hubs/SampleMessageHub from origin: > 
http://localhost:4200 but was ignored because path was not for an allowed 
IdentityServer CORS endpoint

Startup.cs

 public class Startup
    {
        public IConfiguration Configuration { get; }
        public IWebHostEnvironment _environment { get; }

        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            _environment = env;
        }

        public void ConfigureServices(IServiceCollection services)
        {

            services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            }));

            services.AddSignalR();

            services.AddControllersWithViews();

            services.AddIdentityServer(options =>
            {
                options.Events.RaiseSuccessEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseErrorEvents = true;
            })
                    .AddInMemoryIdentityResources(Config.GetIdentityResources())
                    .AddInMemoryApiResources(Config.GetApiResources())
                    .AddInMemoryClients(Config.GetClients())
                    .AddDeveloperSigningCredential()
                    .AddCustomUserStore();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        { 
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseCors("MyPolicy");

            app.UseWebSockets();
            app.UseStaticFiles();
            app.UseIdentityServer();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<SampleHub>("/hubs/SampleMessageHub");

                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Конфигурация выглядит следующим образом:

 public class Config
    {
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                    new IdentityResources.Email()
                };
        }
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {              

                new ApiResource("hubs/SampleMessageHub", "SignalR Hub Resources")
                {
                    // this is needed for introspection when using reference tokens
                    ApiSecrets = { new Secret("secret".Sha256()) }
                }
            };
        }

        // clients want to access resources (aka scopes)
        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client
                {
                    ClientId = "angular-test",
                    AllowedGrantTypes = GrantTypes.Implicit,
                    AccessTokenType = AccessTokenType.Jwt,
                    AccessTokenLifetime = 3600,
                    IdentityTokenLifetime = 3600,
                    UpdateAccessTokenClaimsOnRefresh = true,
                    SlidingRefreshTokenLifetime = 15,
                    AllowOfflineAccess = true,
                    RefreshTokenExpiration = TokenExpiration.Absolute,
                    RefreshTokenUsage = TokenUsage.OneTimeOnly,
                    AlwaysSendClientClaims = true,
                    Enabled = true,
                    AlwaysIncludeUserClaimsInIdToken = true,
                    RedirectUris = new List<string>() { "http://localhost:4200/", "http://localhost:4200/silent-refresh.html" },
                    AllowedScopes = {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email
                    },
                    PostLogoutRedirectUris = new List<string>() { "http://localhost:4200/" },
                    AllowAccessTokensViaBrowser = true,
                    RequireConsent = false
                }
            };
        }
    }

и очень простой концентратор:

public class SampleHub : Hub<ISampleHub>
    {
        public SampleHub()
        {

        }

        Task SendMessage(string message)
        {
            Console.WriteLine("Message received: " + message);
            return Task.CompletedTask;
        }
    }

Вывод журнала с сервера идентификации выглядит следующим образом:


    dbug: IdentityServer4.Hosting.CorsPolicyProvider[0]
      CORS request made for path: /hubs/SampleMessageHub from origin: 
     http://localhost:4200 but was ignored because path was not for an 
     allowed IdentityServer CORS endpoint
    info: Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware[10]
      No CORS policy found for the specified request.
    info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/hubs/SampleMessageHub'
    info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/hubs/SampleMessageHub'
    info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 309.1009ms 101

, и моя ошибка в угловых значениях:

 [2019-10-02T09:35:27.872Z] Information: WebSocket connected to wss://localhost:5001/hubs/SampleMessageHub.
core.js:4002 ERROR Error: Error parsing handshake response: TypeError: Right-hand side of 'instanceof' is not callable
    at HubConnection.push../node_modules/@aspnet/signalr/dist/esm/HubConnection.js.HubConnection.processHandshakeResponse (HubConnection.js:372)
    at HubConnection.push../node_modules/@aspnet/signalr/dist/esm/HubConnection.js.HubConnection.processIncomingData (HubConnection.js:322)
    at WebSocketTransport.HubConnection.connection.onreceive (HubConnection.js:65)
    at WebSocket.webSocket.onmessage (WebSocketTransport.js:107)
    at WebSocket.wrapFn (zone.js:1279)
    at ZoneDelegate.invokeTask (zone.js:431)
    at Object.onInvokeTask (core.js:26246)
    at ZoneDelegate.invokeTask (zone.js:430)
    at Zone.runTask (zone.js:198)
    at ZoneTask.invokeTask [as invoke] (zone.js:513)

Если я создаю новый проект без сервера идентификации - все работает как положено,Каким-то образом должна быть какая-то конфигурация для конечной точки SignalR - но как эта конфигурация должна выглядеть?

Заранее спасибо за вашу помощь.

1 Ответ

0 голосов
/ 02 октября 2019

Попробуйте также добавить свойство AllowedCorsOrigins в метод GetClients(). например,

        public IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client
                {
                    AllowedCorsOrigins =
                    {
                        "http://localhost:4200/",

                    },
                   // Rest of the properties
                }
            }
        }

Причина в том, что теперь вы разрешаете домену CORS (localhost: 4200) доступ к вашему API.

...