如何通过Azure应用注册实现C# WinForms向Azure SignalR Service认证
实现Azure SignalR Service下的WinForms客户端认证授权
1. 配置API端的Azure AD认证
在你的ASP.NET Core Web API中,先配置Azure AD作为身份验证提供者,让SignalR Hub能识别客户端的合法令牌:
- 在
Program.cs中添加Azure AD认证服务:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
确保appsettings.json里的AzureAd配置准确,填入你的租户ID和API应用注册的客户端ID:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "你的租户ID", "ClientId": "你的API应用注册ID" }
- 启用认证和授权中间件,注意要放在路由中间件之前:
app.UseAuthentication(); app.UseAuthorization();
2. 为WinForms客户端获取Azure AD令牌
你的WinForms客户端用IWA认证,通过MSAL.NET获取访问SignalR Hub的令牌:
- 安装
Microsoft.Identity.ClientNuGet包。 - 在客户端代码中初始化MSAL客户端并获取令牌:
var clientId = "你的WinForms应用注册ID"; var tenantId = "你的租户ID"; // 这个范围要和API应用注册中定义的一致 var apiScope = "api://你的API应用注册ID/access_as_user"; var pca = PublicClientApplicationBuilder .Create(clientId) .WithTenantId(tenantId) .WithDefaultRedirectUri() // WinForms默认用https://login.microsoftonline.com/common/oauth2/nativeclient .Build(); var accounts = await pca.GetAccountsAsync(); AuthenticationResult result; try { // 优先使用缓存的令牌 result = await pca.AcquireTokenSilent(new[] { apiScope }, accounts.FirstOrDefault()) .ExecuteAsync(); } catch (MsalUiRequiredException) { // 触发IWA认证(静默使用当前Windows用户身份) result = await pca.AcquireTokenInteractive(new[] { apiScope }) .WithUseEmbeddedWebView(true) // WinForms推荐用内嵌WebView .ExecuteAsync(); }
3. 客户端连接SignalR时携带令牌
在WinForms客户端连接SignalR Hub时,将获取到的令牌添加到请求头:
var connection = new HubConnectionBuilder() .WithUrl("你的API的SignalR Hub地址", options => { options.AccessTokenProvider = () => Task.FromResult(result.AccessToken); }) .Build(); await connection.StartAsync();
4. 配置Azure AD应用注册的权限
在Azure AD的API应用注册中完成以下配置:
- 定义一个API范围(比如
access_as_user),并启用管理员和用户同意。 - 将WinForms的应用注册添加为该API的授权客户端,授予它刚才定义的范围权限。
5. 验证SignalR Hub的授权
确保Hub类上的[Authorize]特性生效,也可以添加更细粒度的策略验证:
[Authorize] public class YourHub : Hub { // Hub方法实现 }
如果需要基于范围的授权,可以配置策略:
[Authorize(Policy = "RequireAccessAsUser")] public class YourHub : Hub { }
然后在Program.cs中添加策略配置:
builder.Services.AddAuthorization(options => { options.AddPolicy("RequireAccessAsUser", policy => policy.RequireClaim("scp", "access_as_user")); });
内容的提问来源于stack exchange,提问作者duta
相关产品推荐
相关产品推荐

