We are implementing AD registered application (deployed as Azure App Service) to access Azure DevOps Rest Api, I have followed the authentication guidance provided for Azure DevOps and using authentication context acquire access token by sending username and password. Although MS is not recommending this authentication process, the reason we are doing this is the user account has permissions to specific access on multiple projects in different organizations. This way we obtain token for that user and access Azure DevOps REST Api's accessible to the user. Basically we created a generic user account that can access DevOps REST Api's from my application.
In the local environment, I am able to get the access token for the user using below code,
AuthenticationContext ctx = new AuthenticationContext("https://login.microsoftonline.com/org.onmicrosoft.com/");
AuthenticationResult result = null;
var username = "********"; // This is your AAD username in the form [email protected].
var password = "********"; // This is your AAD password.
var adalCredential = new UserPasswordCredential(username, password);
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
try
{
result = ctx.AcquireTokenAsync(azureDevOpsResourceId, clientId, adalCredential).Result;
Console.WriteLine("Token expires on: " + result.ExpiresOn);
}
catch (Exception ex)
{
Console.WriteLine("{0}: {1}", ex.GetType(), ex.Message);
}
The same code while accessing through the web application is not working as expected, and throws below ADAL Exception,
System.AggregateException: One or more errors occurred. ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException: parsing_wstrust_response_failed: Parsing WS-Trust response failed
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WsTrust.WsTrustResponse.CreateFromResponseDocument(XDocument responseDocument, WsTrustVersion version)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WsTrust.WsTrustRequest.<SendRequestAsync>d__3.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.ValidateEnd(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenNonInteractiveHandler.<PreTokenRequestAsync>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.ValidateEnd(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.<RunAsync>d__57.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.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.<AcquireTokenCommonAsync>d__37.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.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.<AcquireTokenAsync>d__0.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
Why is this error, parsing_wstrust_response_failed
is occurring when run from the application? I also wanted to know is the approach we are following is correct? do we have an alternate solution that can be implemented to achieve what we are looking for?