Intune数据仓库令牌控制台代码:解决旧API过时无法运行问题
修复Intune数据仓库过时的MSAL令牌获取代码
原代码依赖的AuthenticationContext、ClientCredential、SecureClientSecret均为MSAL.NET的过时API,已被官方弃用,必须使用新版API重构才能正常运行。以下是修复后的完整代码:
using System; using System.Security; using System.Configuration; using Microsoft.Identity.Client; class IntuneDataWarehouse { public static void Main() { Console.WriteLine("Intune Datawarehouse Start"); // 从配置读取参数 var clientId = ConfigurationManager.AppSettings["appId"].ToString(); var clientSecret = ConfigurationManager.AppSettings["appKey"].ToString(); var tenantId = ConfigurationManager.AppSettings["tenantDomain"].ToString(); // 支持租户域名或租户ID // 构建机密客户端应用实例 var confidentialClient = ConfidentialClientApplicationBuilder .Create(clientId) .WithClientSecret(clientSecret) .WithAuthority($"https://login.microsoftonline.com/{tenantId}") .Build(); // 获取应用权限令牌(无用户参与的App-Only模式) var authResult = confidentialClient .AcquireTokenForClient(new[] { "https://api.manage.microsoft.com/.default" }) .ExecuteAsync() .GetAwaiter() .GetResult(); // 调试用:输出令牌信息 Console.WriteLine($"访问令牌已获取:{authResult.AccessToken.Substring(0, 50)}..."); Console.WriteLine("End of run"); } // 原代码缺失的SecureString转换方法(如需保留密钥的安全存储) private static SecureString ConvertToSecureStr(string input) { var secureStr = new SecureString(); foreach (char c in input) { secureStr.AppendChar(c); } secureStr.MakeReadOnly(); return secureStr; } }
关键改动说明
- 替换核心API:用
ConfidentialClientApplicationBuilder替代过时的AuthenticationContext,这是MSAL v3+版本推荐的客户端构建方式 - 适配权限模式:使用
AcquireTokenForClient而非AcquireTokenAsync,专门适配无用户参与的应用程序权限场景 - 规范Scope格式:将原资源路径改为
https://api.manage.microsoft.com/.default,符合Azure AD v2端点的scope规范 - 简化地址拼接:直接使用
https://login.microsoftonline.com/{tenantId}作为权威地址,无需手动拼接token路径
若需保留SecureString存储密钥
可添加以下方法并修改客户端构建代码:
// SecureString转普通字符串(需引用System.Runtime.InteropServices) private static string ConvertToUnsecureStr(SecureString secureStr) { if (secureStr == null) throw new ArgumentNullException(nameof(secureStr)); IntPtr unmanagedStr = IntPtr.Zero; try { unmanagedStr = System.Runtime.InteropServices.Marshal.SecureStringToGlobalAllocUnicode(secureStr); return System.Runtime.InteropServices.Marshal.PtrToStringUni(unmanagedStr); } finally { System.Runtime.InteropServices.Marshal.ZeroFreeGlobalAllocUnicode(unmanagedStr); } }
然后将WithClientSecret(clientSecret)替换为:
.WithClientSecret(ConvertToUnsecureStr(ConvertToSecureStr(clientSecret)))
内容的提问来源于stack exchange,提问作者Chaka
相关产品推荐
相关产品推荐

