使用来自 Windows 服务的身份进行 HubConnection 身份验证
HubConnection Authentication Using Identity From Windows Service
我有一个提供近乎实时数据的集线器。我希望实时数据的提供者能够向所有连接的客户端发送消息。我 运行 遇到的问题是对连接进行身份验证,因为提供程序是 Windows 服务。所以,我正在使用 HubConnectionBuilder
创建一个客户端。当我尝试连接时,出现 401 身份验证失败,这在意料之中。
我正在尝试弄清楚如何使用共享 Entity Framework 数据库中存在的现有身份验证。有没有办法从这个独立服务中使用 UserManager 或 SigninManager 获取身份验证令牌?或者是否有更好的方法允许 HubConnection 进行身份验证?
这是我使用的连接代码:
var notifyConnection = new HubConnectionBuilder()
.WithUrl("https://localhost:5001/notify", options =>
{
options.AccessTokenProvider = () => Task.FromResult(_myAccessToken);
})
.WithAutomaticReconnect()
.Build();
notifyConnection.Closed += async (error) =>
{
if (Debug) _logger.LogInformation("Hub connection closed: " + error.Message);
await Task.Delay(new Random().Next(0, 5) * 1000);
await notifyConnection.StartAsync();
};
try
{
var task = notifyConnection.StartAsync();
task.Wait();
}
catch (Exception ex)
{
if (Debug) _logger.LogInformation("Hub connection start error: " + ex.Message);
}
_myAccessToken
未定义。我正在尝试弄清楚如何获得可以正确验证的有效访问令牌。
编辑:
我试过添加 JWT 身份验证。我可以验证不记名令牌是否已正确生成。但它似乎并未在 Hub
.
上得到验证
我已将以下内容添加到服务配置中:
var key = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes(Configuration["JwtKey"]));
services.AddAuthentication().AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
LifetimeValidator = (before, expires, token, parameters) =>
expires > DateTime.UtcNow,
ValidateAudience = false,
ValidateIssuer = false,
ValidateActor = false,
ValidateLifetime = true,
IssuerSigningKey = key,
NameClaimType = ClaimTypes.NameIdentifier
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
{
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.RequireClaim(ClaimTypes.NameIdentifier);
});
});
我还更新了 HubConnectionBuilder
以使用:
notifyConnection = new HubConnectionBuilder()
.WithUrl(baseUrl + "/notify", options =>
{
options.AccessTokenProvider = async () =>
{
var stringData = JsonConvert.SerializeObject(new { username = "****", password = "****" });
var content = new StringContent(stringData);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await httpClient.PostAsync(baseUrl + "/api/token", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
};
})
.WithAutomaticReconnect()
.Build();
它仍然是 returns 401。当我试图将 Authorize
属性强制为:
[Authorize(AuthenticationSchemes = "Bearer,Cookies")]
然后 returns 500 错误。
因此,在更改 Hub class 上的 Authorize
属性后,我能够让 JWT 身份验证与 built-in 身份验证一起工作。
这是新的 Authorize
属性:
[Authorize(AuthenticationSchemes = "Bearer,Identity.Application")]
我添加了一个简单的令牌生成 API 控制器来提供 HubConnection。以下资源非常有帮助:
https://www.codemag.com/article/1807061/Build-Real-time-Applications-with-ASP.NET-Core-SignalR
我有一个提供近乎实时数据的集线器。我希望实时数据的提供者能够向所有连接的客户端发送消息。我 运行 遇到的问题是对连接进行身份验证,因为提供程序是 Windows 服务。所以,我正在使用 HubConnectionBuilder
创建一个客户端。当我尝试连接时,出现 401 身份验证失败,这在意料之中。
我正在尝试弄清楚如何使用共享 Entity Framework 数据库中存在的现有身份验证。有没有办法从这个独立服务中使用 UserManager 或 SigninManager 获取身份验证令牌?或者是否有更好的方法允许 HubConnection 进行身份验证?
这是我使用的连接代码:
var notifyConnection = new HubConnectionBuilder()
.WithUrl("https://localhost:5001/notify", options =>
{
options.AccessTokenProvider = () => Task.FromResult(_myAccessToken);
})
.WithAutomaticReconnect()
.Build();
notifyConnection.Closed += async (error) =>
{
if (Debug) _logger.LogInformation("Hub connection closed: " + error.Message);
await Task.Delay(new Random().Next(0, 5) * 1000);
await notifyConnection.StartAsync();
};
try
{
var task = notifyConnection.StartAsync();
task.Wait();
}
catch (Exception ex)
{
if (Debug) _logger.LogInformation("Hub connection start error: " + ex.Message);
}
_myAccessToken
未定义。我正在尝试弄清楚如何获得可以正确验证的有效访问令牌。
编辑:
我试过添加 JWT 身份验证。我可以验证不记名令牌是否已正确生成。但它似乎并未在 Hub
.
我已将以下内容添加到服务配置中:
var key = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes(Configuration["JwtKey"]));
services.AddAuthentication().AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
LifetimeValidator = (before, expires, token, parameters) =>
expires > DateTime.UtcNow,
ValidateAudience = false,
ValidateIssuer = false,
ValidateActor = false,
ValidateLifetime = true,
IssuerSigningKey = key,
NameClaimType = ClaimTypes.NameIdentifier
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
{
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.RequireClaim(ClaimTypes.NameIdentifier);
});
});
我还更新了 HubConnectionBuilder
以使用:
notifyConnection = new HubConnectionBuilder()
.WithUrl(baseUrl + "/notify", options =>
{
options.AccessTokenProvider = async () =>
{
var stringData = JsonConvert.SerializeObject(new { username = "****", password = "****" });
var content = new StringContent(stringData);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await httpClient.PostAsync(baseUrl + "/api/token", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
};
})
.WithAutomaticReconnect()
.Build();
它仍然是 returns 401。当我试图将 Authorize
属性强制为:
[Authorize(AuthenticationSchemes = "Bearer,Cookies")]
然后 returns 500 错误。
因此,在更改 Hub class 上的 Authorize
属性后,我能够让 JWT 身份验证与 built-in 身份验证一起工作。
这是新的 Authorize
属性:
[Authorize(AuthenticationSchemes = "Bearer,Identity.Application")]
我添加了一个简单的令牌生成 API 控制器来提供 HubConnection。以下资源非常有帮助:
https://www.codemag.com/article/1807061/Build-Real-time-Applications-with-ASP.NET-Core-SignalR