使用IdentityServer4时,无法访问我的SignalR端点(从javascript)。
设置身份服务器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
启动文件
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
}
};
}
}
和一个真正简单的Hub:
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端点进行一些配置-但是这种配置看起来如何?
在此先感谢您的帮助。
最佳答案
也尝试在AllowedCorsOrigins
方法中添加GetClients()
属性。
例如
public IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
AllowedCorsOrigins =
{
"http://localhost:4200/",
},
// Rest of the properties
}
}
}
原因是您现在允许CORS域(localhost:4200)访问您的API。