使用PowerShell生成签名JWT令牌连接Azure AD与SharePoint遇错求助
问题:PowerShell生成Azure AD客户端断言JWT时出现类型初始化异常
我有一个用于通过证书连接SharePoint的Azure AD应用注册,需要用PostMan测试API调用,而证书认证需要用到客户端断言。我尝试用一段PowerShell脚本从PFX文件生成JWT令牌,但在PS5和PS7中均无法运行,创建Microsoft.IdentityModel.Tokens.X509SigningCredentials对象时出现**“PerTypeValues`1的类型初始值设定项引发异常”**错误。
相关代码:
$x509cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($CertificatePath_Pfx, $CertPassWord) $signingX509Certificate = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath_Pfx, $CertPassWord, 'Export') $claims = new-object 'System.Collections.Generic.Dictionary[String, Object]' $claims['aud'] = $aud $claims['iss' ] = $ClientId $claims['sub'] = $ClientId $claims['jti'] = [GUID]::NewGuid().ToString('D') #$signingCredentials = [Microsoft.IdentityModel.Tokens.X509SigningCredentials]::new($x509cert) $signingCredentials = New-Object -TypeName Microsoft.IdentityModel.Tokens.X509SigningCredentials($signingX509Certificate) $securityTokenDescriptor = [Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor]::new() $securityTokenDescriptor.Claims = $claims $securityTokenDescriptor.SigningCredentials = $signingCredentials $tokenHandler = [Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler]::new() $clientAssertion = $tokenHandler.createToken($securityTokenDescriptor) write-host $clientAssertion
错误信息:
New-Object : Exception calling ".ctor" with "1" argument(s): "The type initializer for 'PerTypeValues`1' threw an exception." At C:\temp\certs\GetClientAssertion.ps1:50 char:24 + ... edentials = New-Object -TypeName Microsoft.IdentityModel.Tokens.X509S ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
解决方案
1. 确保安装并引用正确的身份验证模块
该异常多因缺失依赖包或版本不兼容导致,按以下步骤修复:
- 安装所需NuGet包:
Install-Package Microsoft.IdentityModel.Tokens -Scope CurrentUser Install-Package System.IdentityModel.Tokens.Jwt -Scope CurrentUser
- 在脚本开头添加程序集加载代码(替换
<你的用户名>和<版本号>为实际内容):
Add-Type -Path "C:\Users\<你的用户名>\.nuget\packages\microsoft.identitymodel.tokens\<版本号>\lib\netstandard2.0\Microsoft.IdentityModel.Tokens.dll" Add-Type -Path "C:\Users\<你的用户名>\.nuget\packages\system.identitymodel.tokens.jwt\<版本号>\lib\netstandard2.0\System.IdentityModel.Tokens.Jwt.dll"
2. 优化证书加载逻辑
证书加载时的权限或导出选项可能引发问题,修改加载代码:
# 使用组合权限加载证书,确保密钥可访问 $certFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::ReadWrite ` -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable ` -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet $signingX509Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificatePath_Pfx, $CertPassWord, $certFlags)
3. 使用Az模块简化断言生成(推荐)
无需手动构建JWT,直接借助Az.Accounts模块生成客户端断言:
# 安装Az模块(未安装时执行) Install-Module Az.Accounts -Force -Scope CurrentUser # 加载证书 $cert = Get-PfxCertificate -FilePath $CertificatePath_Pfx -Password (ConvertTo-SecureString $CertPassWord -AsPlainText -Force) # 生成客户端断言 $clientAssertion = New-AzClientAssertion -ClientId $ClientId -Certificate $cert -Resource $aud
4. 检查.NET版本兼容性
确保PowerShell依赖的.NET版本符合模块要求:
- PS5需依赖.NET Framework 4.7.2及以上版本
- PS7需依赖.NET Core 3.1及以上版本
版本过低时,升级对应.NET环境即可。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

