microsoft-authentication-library-for-dotnet
microsoft-authentication-library-for-dotnet copied to clipboard
[Bug] AcquireTokenByUsernamePassword returns Object reference not set to an instance of an object when .Net component called from VB6 app
Logs and network traces Not OK! Start PublicClientApplicationBuilder.Create ok https://login.microsoftonline.com/tiofarma.onmicrosoft.com/ calling AcquireTokenByUsernamePassword - There was an error parsing WS-Trust response from the endpoint. This may occur if there is an issue with your ADFS configuration. See https://aka.ms/msal-net-iwa-troubleshooting for more details. Error Message: Object reference not set to an instance of an object. - at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<GetWsTrustResponseAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<PerformWsTrustMexExchangeAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<FetchAssertionFromWsTrustAsync>d__7.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<GetTokenResponseAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__12.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at DMS6_AzureAuth.AzureAuth.VB$StateMachine_13_LoginTaskWithPwd.MoveNext() - Object reference not set to an instance of an object. - at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<GetWsTrustResponseAsync>d__6.MoveNext()
Which version of MSAL.NET are you using? MSAL.NET 4.46
Platform .NET 4.6.1, VB6
What authentication flow has the issue?
- Desktop / Mobile
- [ ] Interactive
- [ ] Integrated Windows Authentication
- [x] Username Password
- [ ] Device code flow (browserless)
- Web app
- [ ] Authorization code
- [ ] On-Behalf-Of
- Daemon app
- [ ] Service to Service calls
Other?
Is this a new or existing app? This is an existing app that was working up to a few weeks ago.
Repro THE MSAL library is being used in a VB.NET class library which is COM visible. This is being called from a VB6 application and also a VB.NET test app. When Authenticate is called from the VB6 app the Object error is seen and when called from the VB.net test app it works.
Imports System.Collections.Generic
Imports System.Threading.Tasks
Imports Microsoft.Identity.Client
Imports System.Configuration
Imports DMS6_AzureAuth
Public Interface iAzureAuth_Interface
ReadOnly Property ClientID As String
ReadOnly Property Authority As String
Property ConfigFolder As String 'this is set by calling application so that DLL knows where to look for config file
Function Authenticate(UserUPN As String, UserPwd As String, ByRef ErrorMessage As String) As Boolean
End Interface
Public Class AzureAuth
Implements iAzureAuth_Interface
Friend client_id As String = Nothing
Friend authority As String = Nothing
Friend config_path As String = Nothing
Public ReadOnly Property ClientID As String Implements iAzureAuth_Interface.ClientID
Get
Return client_id
End Get
End Property
Private ReadOnly Property iAzureAuth_Interface_Authority As String Implements iAzureAuth_Interface.Authority
Get
Return authority
End Get
End Property
Public Property ConfigFolder As String Implements iAzureAuth_Interface.ConfigFolder
Get
Return config_path
End Get
Set(value As String)
config_path = value
value += "\DMS6_AzureAuth.DLL" '& System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
Try
'reset before loading config
client_id = String.Empty
authority = String.Empty
Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(value)
If Not config.HasFile Then
Throw New Exception(String.Format("Configuration file missing. Check DMS6_AzureAuth.DLL.config in the following path {0}", config_path))
End If
Dim settings = config.AppSettings
Try
client_id = settings.Settings("client_id").Value
authority = settings.Settings("authority").Value
Catch ex As Exception
Dim err As String = String.Format("Invalid config file {0}. Error: {1}", value, ex.Message)
Throw New Exception(err)
End Try
Catch ex As Exception
'config not found or contains missing settings values
Throw New Exception(ex.Message)
End Try
End Set
End Property
Private Class AuthParams
Public UserName As String
Public Password As String
Public ErrorMessage As String
End Class
Public Function Authenticate(UserUPN As String, UserPwd As String, ByRef ErrorInfo As String) As Boolean Implements iAzureAuth_Interface.Authenticate
Dim taskParams = New AuthParams With {.UserName = UserUPN, .Password = UserPwd, .ErrorMessage = String.Empty}
Dim task As Task(Of Boolean) = LoginTaskWithPwd(taskParams)
If task.Result() Then
'Console.WriteLine("Authorized!")
ErrorInfo = taskParams.ErrorMessage
Return True
Else
ErrorInfo = taskParams.ErrorMessage
'Console.WriteLine("Not Authorized")
Return False
End If
End Function
Private Async Function LoginTaskWithPwd(params As AuthParams) As Task(Of Boolean)
Dim publicClientApp As IPublicClientApplication
Dim authResult As AuthenticationResult
Dim username As String
Dim password As New Security.SecureString()
Dim scopes As New List(Of String)
Dim accessToken As String = String.Empty
Try
'check if clientid and authority have been set first
If String.IsNullOrEmpty(client_id) OrElse String.IsNullOrEmpty(authority) Then
Dim err As String = String.Format("Invalid configuration file. Check DMS6_AzureAuth.DLL.config in the following path {0}.", config_path)
Throw New Exception(err)
End If
If String.IsNullOrEmpty(params.Password) Then
Dim err As String = "Blank password not allowed"
Throw New Exception(err)
End If
params.ErrorMessage = "Start"
'NB this could error if the client_id is invalid
publicClientApp = PublicClientApplicationBuilder.Create(client_id).WithAuthority(authority).Build()
params.ErrorMessage += " PublicClientApplicationBuilder.Create ok "
params.ErrorMessage += publicClientApp.Authority
username = params.UserName
For Each ch In params.Password
password.AppendChar(ch)
Next
scopes.Add("user.read")
params.ErrorMessage += " calling AcquireTokenByUsernamePassword "
authResult = Await publicClientApp.AcquireTokenByUsernamePassword(scopes, username, password).ExecuteAsync()
params.ErrorMessage += " AcquireTokenByUsernamePassword ok "
accessToken = authResult.AccessToken
params.ErrorMessage += " accessToken ok"
' Catch ex As MsalUiRequiredException When (ex.Message.Contains("AADSTS65001"))
' // Here are the kind of error messages you could have, And possible mitigations
' // ------------------------------------------------------------------------
' // MsalUiRequiredException: AADSTS65001 : The user Or administrator has Not consented to use the application
' // with ID '{appId}' named '{appName}'. Send an interactive authorization request for this user and resource.
' // Mitigation you need to get user consent first. This can be done either statically (through the portal),
' /// Or dynamically (but this requires an interaction with Azure AD, which Is Not possible with
' // the username/password flow)
' // Statically: in the portal by doing the following in the "API permissions" tab of the application registration:
' // 1. Click "Add a permission" And add all the delegated permissions corresponding to the scopes you want (for instance
' // User.Read And User.ReadBasic.All)
' // 2. Click "Grant/revoke admin consent for <tenant>") And click "yes".
' // Dynamically, if you are Not using .NET Core (which does Not have any Web UI) by
' // calling (once only) AcquireTokenInteractive.
' // remember that Username/password Is for public client applications that Is desktop/mobile applications.
' // If you are using .NET core Or don't want to call AcquireTokenInteractive, you might want to:
' // - use device code flow (See https://aka.ms/msal-net-device-code-flow)
' // - Or suggest the user to navigate to a URL to consent: https : //login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read
' // ------------------------------------------------------------------------
Catch ex As MsalUiRequiredException When (ex.Message.Contains("AADSTS50079")) 'ALSO AADSTS50076 (as seen at TIO
' // ------------------------------------------------------------------------
' // ErrorCode: invalid_grant
' // SubError: basic_action
' // MsalUiRequiredException: AADSTS50079 : The user Is required to use multi-factor authentication.
' // The tenant admin for your organization has chosen to oblige users to perform multi-factor authentication.
' // Mitigation: none for this flow
' // Your application cannot use the Username/Password grant.
' // Like in the previous case, you might want to use an interactive flow (AcquireTokenInteractive()),
' // Or Device Code Flow instead.
' // Note this Is one of the reason why using username/password Is Not recommended;
' // ------------------------------------------------------------------------
'Console.WriteLine("The user Is required to use multi-factor authentication.{0}", ex.Message)
'For DMS assume that if we error at this point that the password was accepted
params.ErrorMessage = ex.Message
accessToken = "MFA request"
Catch ex As MsalUiRequiredException When (ex.Message.Contains("AADSTS50076"))
'For DMS assume that if we error at this point that the password was accepted
params.ErrorMessage = ex.Message
accessToken = "MFA request"
'Catch ex As MsalUiRequiredException When (ex.Message.Contains("AADSTS70002"))
' ' // ------------------------------------------------------------------------
' ' // ex.ErrorCode: invalid_grant
' ' // subError: null
' ' // Message = "AADSTS70002: Error validating credentials.
' ' // AADSTS50126: Invalid username or password
' ' // In the case of a managed user (user from an Azure AD tenant opposed to a
' ' // federated user, which would be owned
' ' // in another IdP through ADFS), the user has entered the wrong password
' ' // Mitigation: ask the user to re-enter the password
' ' // ------------------------------------------------------------------------
' 'Console.WriteLine("The user has entered the wrong password.{0}", ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalUiRequiredException When (ex.Message.Contains("ADSTS50034"))
' ' // ------------------------------------------------------------------------
' ' // ex.ErrorCode: invalid_grant
' ' // subError: null
' ' // MsalServiceException: ADSTS50034: To sign into this application the account must be added to
' ' // the {domainName} directory.
' ' // or The user account does not exist in the {domainName} directory. To sign into this application,
' ' // the account must be added to the directory.
' ' // The user was not found in the directory
' ' // Explanation: wrong username
' ' // Mitigation: ask the user to re-enter the username.
' ' // ------------------------------------------------------------------------
' 'Console.WriteLine("The user was not found in the directory.{0}", ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalServiceException When (ex.ErrorCode = "invalid_request")
' ' // ------------------------------------------------------------------------
' ' // AADSTS90010: The grant type is not supported over the /common or /consumers endpoints.
' ' // Please use the /organizations or tenant-specific endpoint.
' ' // you used common.
' ' // Mitigation: as explained in the message from Azure AD, the authority you use in the application needs
' ' // to be tenanted or otherwise "organizations". change the
' ' // "Tenant": property in the appsettings.json to be a GUID (tenant Id), or domain name (contoso.com)
' ' // if such a domain is registered with your tenant
' ' // or "organizations", if you want this application to sign-in users in any Work and School accounts.
' ' // ------------------------------------------------------------------------
' 'Console.WriteLine(ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalServiceException When (ex.ErrorCode = "unauthorized_client")
' ' // ------------------------------------------------------------------------
' ' // AADSTS700016: Application with identifier '{clientId}' was not found in the directory '{domain}'.
' ' // This can happen if the application has not been installed by the administrator of the tenant or consented
' ' // to by any user in the tenant.
' ' // You may have sent your authentication request to the wrong tenant
' ' // Cause: The clientId in the appsettings.json might be wrong
' ' // Mitigation: check the clientId and the app registration
' ' // ------------------------------------------------------------------------
' 'Console.WriteLine(ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalServiceException When (ex.ErrorCode = "invalid_client")
' ' // ------------------------------------------------------------------------
' ' // AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.
' ' // Explanation: this can happen if your application was not registered as a public client application in Azure AD
' ' // Mitigation: in the Azure portal, edit the manifest for your application and set the `allowPublicClient` to `true`
' ' // ------------------------------------------------------------------------
' 'Console.WriteLine("Invalid client. this can happen if your application was not registered as a public client application in Azure AD Mitigation: in the Azure portal, edit the manifest for your application and set the `allowPublicClient` to `true`{0}", ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalServiceException
' 'Console.WriteLine("MsalServiceException{0}{1}", ex.ErrorCode, ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalClientException When (ex.ErrorCode = "unknown_user_type")
' '{
' ' // Message = "Unsupported User Type 'Unknown'. Please see https://aka.ms/msal-net-up"
' ' // The user Is Not recognized as a managed user, Or a federated user. Azure AD was Not
' ' // able to identify the IdP that needs to process the user
' ' Throw New ArgumentException("U/P: Wrong username", ex);
' '}
' 'Throw New ArgumentException("U/P: Wrong username", ex)
' 'Console.WriteLine("U/P: Wrong username{0}", ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalClientException When (ex.ErrorCode = "user_realm_discovery_failed")
' '{
' ' // The user Is Not recognized as a managed user, Or a federated user. Azure AD was Not
' ' // able to identify the IdP that needs to process the user. That's for instance the case
' ' // if you use a phone number
' ' Throw New ArgumentException("U/P: Wrong username", ex);
' '}
' 'Console.WriteLine("U/P: Wrong username{0}", ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalClientException When (ex.ErrorCode = "unknown_user")
' '{
' ' // the username was probably empty
' ' // ex.Message = "Could not identify the user logged into the OS. See https://aka.ms/msal-net-iwa for details."
' ' Throw New ArgumentException("U/P: Wrong username", ex);
' '}
' 'Console.WriteLine("U/P: Wrong username{0}{1}", ex.ErrorCode, ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalClientException When (ex.ErrorCode = "parsing_wstrust_response_failed")
' '{
' ' // ------------------------------------------------------------------------
' ' // In the case of a Federated user (that Is owned by a federated IdP, as opposed to a managed user owned in an Azure AD tenant)
' ' // ID3242: The security token could Not be authenticated Or authorized.
' ' // The user does Not exist Or has entered the wrong password
' ' // ------------------------------------------------------------------------
' '}
' 'Console.WriteLine("The user does Not exist Or has entered the wrong password{0}{1}", ex.ErrorCode, ex.Message)
' Throw New Exception(ex.Message, ex)
'Catch ex As MsalClientException
' 'Console.WriteLine("MsalClientException{0}{1}", ex.ErrorCode, ex.Message)
' Throw New Exception(ex.Message, ex)
Catch ex As Exception
'Console.WriteLine("Unknown error{0}{1}", ex.Message)
'Throw New Exception(ex.Message, ex)
Dim msgs As New List(Of String)
'Dim fullerror As String = ex.ToString()
msgs.Add(params.ErrorMessage)
Do
msgs.Add(ex.Message)
msgs.Add(ex.StackTrace.ToString())
ex = ex.InnerException
Loop While Not (ex Is Nothing)
params.ErrorMessage = String.Join(" - ", msgs)
'params.ErrorMessage += String.Join(" ## ", fullerror)
End Try
Return accessToken <> String.Empty
End Function
End Class
Module DMS6_AzureAuth_Test
Sub Main()
Dim username As String
Dim password As String = String.Empty
Dim cki As ConsoleKeyInfo
Dim azureAuth As DMS6_AzureAuth.iAzureAuth_Interface
Dim errmsg As String = String.Empty
Try
azureAuth = New DMS6_AzureAuth.AzureAuth
'set config path
azureAuth.ConfigFolder = Environment.CurrentDirectory
Catch ex As Exception
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Exception raised:")
Console.WriteLine(ex.Message)
End Try
Console.ForegroundColor = ConsoleColor.Yellow
Console.Write("Client ID:")
Console.ResetColor()
Console.WriteLine(azureAuth.ClientID)
Console.ForegroundColor = ConsoleColor.Yellow
Console.Write("Authority:")
Console.ResetColor()
Console.WriteLine(azureAuth.Authority)
Do
password = String.Empty
Console.ResetColor()
Console.Write("Enter username:")
Console.ForegroundColor = ConsoleColor.Magenta
username = Console.ReadLine()
Console.ResetColor()
Console.Write("Enter password:")
Console.ForegroundColor = ConsoleColor.Magenta
Do
cki = Console.ReadKey(True)
If cki.Key <> ConsoleKey.Enter Then
Console.Write("*")
password += cki.KeyChar
End If
Loop While cki.Key <> ConsoleKey.Enter
Console.WriteLine()
Console.ForegroundColor = ConsoleColor.Yellow
Console.WriteLine("Authorising...")
Try
If azureAuth.Authenticate(username, password, errmsg) Then
Console.ForegroundColor = ConsoleColor.Green
Console.WriteLine("Authorized!")
Console.WriteLine(errmsg)
Else
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Not Authorized!")
Console.WriteLine(errmsg)
End If
Catch ex As Exception
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Exception raised:")
Console.WriteLine(ex.Message)
Console.WriteLine(ex.InnerException.Message)
End Try
Console.ResetColor()
Console.WriteLine("Press a ESC to end, otherwise retry")
cki = Console.ReadKey(True)
If cki.Key = ConsoleKey.Escape Then Exit Do
If cki.Key = ConsoleKey.R Then
're-read config
Try
azureAuth.ConfigFolder = Environment.CurrentDirectory
Console.ForegroundColor = ConsoleColor.Yellow
Console.Write("Client ID:")
Console.ResetColor()
Console.WriteLine(azureAuth.ClientID)
Console.ForegroundColor = ConsoleColor.Yellow
Console.Write("Authority:")
Console.ResetColor()
Console.WriteLine(azureAuth.Authority)
Console.ResetColor()
Catch ex As Exception
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Exception raised:")
Console.WriteLine(ex.Message)
End Try
End If
Loop
End Sub
End Module
Option Explicit
Private moAzureAuth As iAzureAuth_Interface 'CI/DMS6/CRN1034
Private Sub cmdLogon_Click()
Dim strErrorDesc As String
On Error GoTo ErrTrap
txtResult.Text = "..."
Me.Refresh
If moAzureAuth Is Nothing Then
Set moAzureAuth = New DMS6_AzureAuth.AzureAuth
moAzureAuth.ConfigFolder = App.Path 'this could error if config not found or if data missing
End If
If moAzureAuth.Authenticate(Trim$(txtUserID), txtPwd, strErrorDesc) Then
txtResult.Text = "OK" * vbCrLf & strErrorDesc
Else
txtResult.Text = "Not OK!" & vbCrLf & strErrorDesc
End If
Exit Sub
ErrTrap:
txtResult.Text = Err.Description
End Sub
Expected behavior The VB6 app authenticates correctly.
Actual behavior The VB6 app gives an object error When the same class library is called from a VB.NET test client AcquireTokenByUsernamePassword returns without error.
Authorising...
Authorized!
Start PublicClientApplicationBuilder.Create ok https://login.microsoftonline.com
/tiofarma.onmicrosoft.com/ calling AcquireTokenByUsernamePassword AcquireTokenB
yUsernamePassword ok accessToken ok
Press a ESC to end, otherwise retry
Possible solution
Additional context / logs / screenshots / links to code
Add any other context about the problem here, such as logs and screenshots, and even links to code.
Can you try to use WAM instead? It will do the ROPC flow instead of MSAL, and it's a Windows component. See https://aka.ms/msal-net-wam
Thanks Bogdan,
Are there any examples of using ROPC with WAM?
Thanks Craig
Craig Woods Technical Lead
t. +44 (0)1722 424100 e. @.*** www.ciprecision.comCIPrecision
Any opinions expressed in this email are those of the individual author and do not necessarily reflect those of the Company. The Company does not take any responsibility for the views of the author. This email and any files transmitted with it are confidential and solely for the use of the intended recipient. If you are not the intended recipient or the person responsible for delivering to the intended recipient, be advised that you have received this email in error and that any use is strictly prohibited. If you have received this email in error, advise the sender immediately by using the reply facility in your email software. We have taken every reasonable precaution to ensure that any attachments to this email are swept for viruses. However, we cannot accept liability for any damage sustained as a result of software viruses and advise you to carry out your own virus checks before opening any attachments. CI Electronics Limited, trading as CI Precision, registered in England and Wales, company number 00850159 CI Systems Limited, trading as CI Precision, registered in England and Wales, company number 00929573 2 Brunel Road, Churchfields, Salisbury, Wiltshire SP2 7PX
From: Bogdan Gavril @.> Sent: 22 August 2022 14:40 To: AzureAD/microsoft-authentication-library-for-dotnet @.> Cc: Craig Woods @.>; Author @.> Subject: Re: [AzureAD/microsoft-authentication-library-for-dotnet] [Bug] AcquireTokenByUsernamePassword returns Object reference not set to an instance of an object when .Net component called from VB6 app (Issue #3614)
CAUTION: This email originated from outside your organization. Exercise caution when opening attachments or clicking links, especially from unknown senders.
Can you try to use WAM instead? It will do the ROPC flow instead of MSAL, and it's a Windows component. See https://aka.ms/msal-net-wam
— Reply to this email directly, view it on GitHubhttps://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/3614#issuecomment-1222378347, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AH2Q7YQSGRDYW3YB57O62U3V2N7J3ANCNFSM565XE5BQ. You are receiving this because you authored the thread.Message ID: @.@.>>
Just enable WAM as described here on the PublicClientApplication object - https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/WAM#to-enable-wam-preview
Then call AcquireTokenByUsernamePassword. WAM will take over.
Thanks Bogdan,
I will give that a try.
Best regards Craig
Craig Woods Technical Lead
t. +44 (0)1722 424100 e. @.*** www.ciprecision.comCIPrecision
Any opinions expressed in this email are those of the individual author and do not necessarily reflect those of the Company. The Company does not take any responsibility for the views of the author. This email and any files transmitted with it are confidential and solely for the use of the intended recipient. If you are not the intended recipient or the person responsible for delivering to the intended recipient, be advised that you have received this email in error and that any use is strictly prohibited. If you have received this email in error, advise the sender immediately by using the reply facility in your email software. We have taken every reasonable precaution to ensure that any attachments to this email are swept for viruses. However, we cannot accept liability for any damage sustained as a result of software viruses and advise you to carry out your own virus checks before opening any attachments. CI Electronics Limited, trading as CI Precision, registered in England and Wales, company number 00850159 CI Systems Limited, trading as CI Precision, registered in England and Wales, company number 00929573 2 Brunel Road, Churchfields, Salisbury, Wiltshire SP2 7PX
From: Bogdan Gavril @.> Sent: 24 August 2022 11:47 To: AzureAD/microsoft-authentication-library-for-dotnet @.> Cc: Craig Woods @.>; Author @.> Subject: Re: [AzureAD/microsoft-authentication-library-for-dotnet] [Bug] AcquireTokenByUsernamePassword returns Object reference not set to an instance of an object when .Net component called from VB6 app (Issue #3614)
CAUTION: This email originated from outside your organization. Exercise caution when opening attachments or clicking links, especially from unknown senders.
Just enable WAM as described here on the PublicClientApplication object - https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/WAM#to-enable-wam-preview
Then call AcquireTokenByUsernamePassword. WAM will take over.
— Reply to this email directly, view it on GitHubhttps://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/3614#issuecomment-1225550004, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AH2Q7YSQNYZMYKO4GE7F53TV2X4SZANCNFSM565XE5BQ. You are receiving this because you authored the thread.Message ID: @.@.>>
I have tried using WithBrokerPreview but I get the same results. My vb.net test client works correctly but when I access the same .net library using COM I see the same object error:
Not OK! Start PublicClientApplicationBuilder.Create (with broker preview) ok https://login.microsoftonline.com/tiofarma.onmicrosoft.com/ calling AcquireTokenByUsernamePassword - There was an error parsing WS-Trust response from the endpoint. This may occur if there is an issue with your ADFS configuration. See https://aka.ms/msal-net-iwa-troubleshooting for more details. Error Message: Object reference not set to an instance of an object. - at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<GetWsTrustResponseAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<PerformWsTrustMexExchangeAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<FetchAssertionFromWsTrustAsync>d__7.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<GetTokenResponseAsync>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__12.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at DMS6_AzureAuth.AzureAuth.VB$StateMachine_13_LoginTaskWithPwd.MoveNext() - Object reference not set to an instance of an object. - at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<GetWsTrustResponseAsync>d__6.MoveNext()
I have also encountered this issue in a C# application. It doesn't matter which library I use, the end result is always the same:
There was an error parsing WS-Trust response from the endpoint. This may occur if there is an issue with your ADFS configuration. See https://aka.ms/msal-net-iwa-troubleshooting for more details. Error Message: Object reference not set to an instance of an object.
at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<GetWsTrustResponseAsync>d__6.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Microsoft.Identity.Client.WsTrust.CommonNonInteractiveHandler.<PerformWsTrustMexExchangeAsync>d__5.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<FetchAssertionFromWsTrustAsync>d__7.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<GetTokenResponseAsync>d__6.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Identity.Client.Internal.Requests.UsernamePasswordRequest.<ExecuteAsync>d__5.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__12.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.<ExecuteAsync>d__5.MoveNext()
If you write a C# app and try with the same user, do you get the same error or does it work? Can we get logs please?
Yes, this fails within a new C# app for any user. We have managed to trace down the issue though. Using packet capture we noticed the ADFS server is returning the error "MSIS7068: Access denied.".
It appears that when the Microsoft.Identity.Client.WsTrust library recieves back a SOAP from the ADFS server it doesn't handle it gracefully, and simply throws a null ref exception.
Is it possible to copy paste the request and response that results in "Access Denied" ? So that we can fix MSAL.
C# snippet:
var clientAuth = PublicClientApplicationBuilder("xxxx").WithTenantId(xxxx).Build();
var token = await clientAuth.AcquireTokenByUsernamePassword(scopes, "user", "pass").ExecuteAsync();
The request being generated and sent to the ADFS server is as follows:
<s:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> <s:Header> <wsa:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action> wsa:MessageIDurn:uuid:d73362f9-aaaa-4be1-8416-ca380baaaaa</wsa:MessageID> wsa:ReplyTo wsa:Addresshttp://www.w3.org/2005/08/addressing/anonymous</wsa:Address> </wsa:ReplyTo> <wsa:To s:mustUnderstand="1">https://xxxxxx.com/adfs/services/trust/2005/usernamemixed</wsa:To> <wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsu:Timestamp wsu:Id="MSATimeStamp"> wsu:Created2022-10-18T13:55:05.068Z</wsu:Created> wsu:Expires2022-10-18T14:05:05.068Z</wsu:Expires> </wsu:Timestamp> <wsse:UsernameToken wsu:Id="UnPwSecTok2005-ca81f206-4d53-bbbb-aaaa-6a8a30993111"> wsse:Usernamexxxxxx</wsse:Username> wsse:Passwordxxxxxx</wsse:Password> </wsse:UsernameToken> </wsse:Security> </s:Header> <s:Body> <wst:RequestSecurityToken xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> wsa:EndpointReference wsa:Addressurn:federation:MicrosoftOnline</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> wst:KeyTypehttp://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</wst:KeyType> wst:RequestTypehttp://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType> </wst:RequestSecurityToken> </s:Body> </s:Envelope>
The response from the ADFS server is:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action> <a:RelatesTo>urn:uuid:d73362f9-aaaa-4be1-8416-ca380baaaaa</a:RelatesTo> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="_0"> <u:Created>2022-10-18T13:54:59.751Z</u:Created> <u:Expires>2022-10-18T13:59:59.751Z</u:Expires> </u:Timestamp> </o:Security> </s:Header> <s:Body> <s:Fault> <s:Code> <s:Value>s:Sender</s:Value> <s:Subcode> <s:Value xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/trust">a:FailedAuthentication</s:Value> </s:Subcode> </s:Code> <s:Reason> <s:Text xml:lang="en-US">MSIS7068: Access denied.</s:Text> </s:Reason> <s:Detail> <IssuanceAuthorizationFault xmlns="http://schemas.microsoft.com/ws/2009/12/identityserver/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/> </s:Detail> </s:Fault> </s:Body> </s:Envelope>