使用C# WinForms调用Azure语音服务遇401认证错误求助
问题
在C# Windows Forms应用中调用Azure语音服务时,持续收到错误:
WebSocket upgrade failed: Authentication error (401). Please check subscription information and region name
已完成以下配置:
- 语音资源为S0层级
- 注册Entra ID应用并授予Microsoft Cognitive Services权限
- 在语音资源的角色分配中,为Entra ID应用(服务主体)添加Cognitive Services Speech User和Cognitive Services Speech Contributor权限
- 为语音资源创建自定义域名和专用端点
附上相关代码:
TokenRequestContext context = new Azure.Core.TokenRequestContext(new string[] { "https://cognitiveservices.azure.com/.default" }); var credential = new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions { TenantId = "", ClientId = "" }); var browserToken = credential.GetToken(context); string aadToken = browserToken.Token; // Define the custom domain endpoint for your Speech resource. var endpoint = "wss://customdomain.cognitiveservices.azure.com/stt/speech/universal/v2"; string resourceId = "/subscriptions/..."; string region = "eastus"; // You need to include the "aad#" prefix and the "#" (hash) separator between resource ID and Microsoft Entra access token. var authorizationToken = $"aad#{resourceId}#{aadToken}"; SpeechTranslationConfig translationConfig = SpeechTranslationConfig.FromAuthorizationToken(authorizationToken, region); translationConfig.SpeechRecognitionLanguage = "en-US"; translationConfig.AddTargetLanguage("fr"); // English to French // Enable Cognitive Services Logging string logFilePath = "speech-sdk-log.txt"; translationConfig.SetProperty(PropertyId.Speech_LogFilename, logFilePath); Console.WriteLine($"📄 Logging enabled. Logs will be saved to: {logFilePath}"); using var recognizer = new TranslationRecognizer(translationConfig); Console.WriteLine("Speak something..."); var result = await recognizer.RecognizeOnceAsync(); if (result.Reason == ResultReason.TranslatedSpeech) { Console.WriteLine($"Original: {result.Text}"); foreach (var (lang, translation) in result.Translations) { Console.WriteLine($"Translated [{lang}]: {translation}"); } } else if (result.Reason == ResultReason.Canceled) { var cancellation = CancellationDetails.FromResult(result); Console.WriteLine($"Speech translation canceled: {cancellation.Reason}"); if (cancellation.Reason == CancellationReason.Error) { Console.WriteLine($"Error Code: {cancellation.ErrorCode}"); Console.WriteLine($"Error Details: {cancellation.ErrorDetails}"); } } else { Console.WriteLine($"Speech Recognition Failed: {result.Reason}"); }
排查与解决方案
针对你遇到的401认证错误,结合配置和代码,以下是可能遗漏的环节:
1. 修正Token请求的Scope
当前使用的通用Scopehttps://cognitiveservices.azure.com/.default不匹配自定义端点场景,需替换为语音资源专属Scope:
TokenRequestContext context = new Azure.Core.TokenRequestContext(new string[] { "https://customdomain.cognitiveservices.azure.com/.default" });
2. 绑定自定义端点到配置
代码中定义了自定义端点URL,但未绑定到SpeechTranslationConfig,SDK默认会调用公共区域端点,需添加:
translationConfig.SetProperty(PropertyId.SpeechServiceConnection_Endpoint, endpoint);
3. 确认角色分配的作用域与生效状态
- 检查角色分配的作用域是否精准指向你的语音资源(而非订阅/资源组层级)
- 等待角色分配同步完成(Azure角色配置可能需要1-5分钟生效)
4. 验证AAD Token有效性
解码获取到的aadToken,检查关键字段:
aud(受众):必须匹配自定义域名的Scopeiss(颁发者):需与你的Entra ID租户地址一致exp(过期时间):确保Token未过期
5. 确认登录身份权限
使用InteractiveBrowserCredential登录的身份,必须是已被分配语音资源角色的用户/服务主体,且登录租户与配置的TenantId一致
6. 检查自定义端点状态
确认自定义域名已完成DNS解析,且语音资源的专用端点状态为已启用
内容的提问来源于stack exchange,提问作者SaanjS
相关产品推荐
相关产品推荐

