我尝试使用 Azure AD 和证书以及控制台应用程序获取身份验证 token 。 当我尝试获取身份验证 token 时,我收到“ObjectC 对象引用未设置为对象的实例”。
这是代码
string _path = @"path_to_cert_file";
// Load the certificate into an X509Certificate object.
var cert_file = System.IO.File.ReadAllBytes(_path);
X509Certificate2 cert = new X509Certificate2(cert_file);
//byte[] certificateContents = Convert.FromBase64String(_options.Certificate);
//X509Certificate2 certificate = new X509Certificate2(certificateContents);
ClientCertificate = new ClientAssertionCertificate("clint_id", cert);
TokenCache cache = new TokenCache();
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token", false, cache);
AuthenticationResult result = null;
string o365Token = "";
try
{
result = await authContext.AcquireTokenAsync("https://graph.microsoft.com", ClientCertificate);
o365Token = result.AccessToken;
}
catch (Exception ex)
{
throw;
}
当我尝试获取 token 时,我遇到了此堆栈跟踪错误
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Platform.SigningHelper.SignWithCertificate(String message, X509Certificate2 certificate)
at Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate.Sign(String message)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.ClientCreds.JsonWebToken.Sign(IClientAssertionCertificate credential, Boolean sendX5c)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.ClientCreds.ClientKey.AddToParameters(IDictionary`2 parameters)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.DictionaryRequestParameters..ctor(String resource, ClientKey clientKey)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.<SendTokenRequestAsync>d__72.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.<CheckAndAcquireTokenUsingBrokerAsync>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.<RunAsync>d__60.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.<AcquireTokenForClientCommonAsync>d__37.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.<AcquireTokenAsync>d__61.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TestTeams.Program.<GetTokenAsync>d__10.MoveNext() in
最佳答案
我最近在尝试从文件读取 X509Certificate2 并使用它创建 ClientAssertionCertificate 时也遇到了这个问题。原来是证书本身的问题。文件中没有私钥,这就是导致“对象未设置”异常的原因:
Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Platform.SigningHelper.SignWithCertificate(字符串消息,X509Certificate2证书)。
将证书导出到文件时,请确保包含私钥并对其进行密码保护。正如Tony Ju提到的,你也需要更新权限。那么以下代码应该适合您:
string _path = @"path_to_cert_file";
string _password = "cert file password";
// Load the certificate into an X509Certificate object.
X509Certificate2 cert = new X509Certificate2(_path, _password);
ClientCertificate = new ClientAssertionCertificate("clint_id", cert);
TokenCache cache = new TokenCache();
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/{tenant_id}", false, cache);
AuthenticationResult result = null;
string o365Token = "";
try
{
result = await authContext.AcquireTokenAsync("https://graph.microsoft.com", ClientCertificate);
o365Token = result.AccessToken;
}
catch (Exception ex)
{
throw;
}
关于azure - 使用证书获取 token 时,未将对象引用设置为对象的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60103919/