C
CephDigital
Guest
So I have made a DLL to generate an authentication token in C# (.NET Framework V4.8) with a test UI to check it works, which it does. Login screen appears, I can login and generate an authentication token. Yet when I run the same method in Openedge, I get an "Object reference not set to an instance of an object.'" error.
I first thought it was related to the
Authentication Method:
Continue reading...
I first thought it was related to the
firstAccount
variable as it returns a null value when set. I checked the variables for when it's ran in C# and in Openedge with useAsync
set to both false
and true
and they end up the same yet Openedge complains a null value is passed and C# doesn't. I then added in a check if the firstAccount
variable is null so that it skips getting the account silently and goes straight into the interactive yet I'm still getting the same error even with .WithAccount(firstAccount)
commented out. Everything else has a value and is the same between the C# and Openedge. The login is triggered by calling the LoginSync() method in both the test UI and Openedge. Anyone got any ideas as to why it does this and how to fix it?Authentication Method:
Code:
public IPublicClientApplication App {
get {
if (_app == null)
{
BuildApp();
}
return _app;
}
}
public BaseRequests Client
{
get
{
if (_client == null)
{
BuildClient();
}
return _client;
}
}
public void BuildApp()
{
_app = null;
_app = PublicClientApplicationBuilder.Create(_clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, _tenantId)
.WithDefaultRedirectUri()
.Build();
}
public string BuildClient()
{
var token = GetAccessToken(true);
_client = new BaseRequests(_baseURL, token);
return token;
}
public string LoginSync()
{
BuildApp();
return BuildClient();
}
private string GetAccessToken(bool useAsync)
{
if (useAsync)
{
return Task.Run(() => GetAccessTokenAsync()).GetAwaiter().GetResult();
}
AuthenticationResult authResult = null;
IPublicClientApplication app = App;
var accounts = Task.Run(() => app.GetAccountsAsync()).GetAwaiter().GetResult();
IAccount firstAccount = accounts.FirstOrDefault();
try
{
if (firstAccount != null)
{
try
{
authResult = Task.Run(() => app.AcquireTokenSilent(_scopes, firstAccount)
.ExecuteAsync()
).GetAwaiter().GetResult();
}
catch (Exception ex)
{
return $"Error Acquiring Token Silently:{Environment.NewLine}{ex}";
}
}
else
{
try
{
authResult = Task.Run(() =>
app.AcquireTokenInteractive(_scopes)
.WithAccount(firstAccount)
.WithPrompt(Prompt.SelectAccount)
.ExecuteAsync()
).GetAwaiter().GetResult();
}
catch (MsalException msalex)
{
return $"Error Acquiring Token:{Environment.NewLine}{msalex}";
}
}
}
catch (Exception ex)
{
return $"Error Acquiring Token{Environment.NewLine}{ex}";
}
return authResult.AccessToken;
}
private async Task<string> GetAccessTokenAsync()
{
AuthenticationResult authResult = null;
IPublicClientApplication app = App;
var accounts = await app.GetAccountsAsync();
var firstAccount = accounts.FirstOrDefault();
try
{
authResult = await app.AcquireTokenSilent(_scopes, firstAccount)
.ExecuteAsync();
}
catch (MsalUiRequiredException)
{
try
{
authResult = await app.AcquireTokenInteractive(_scopes)
.WithAccount(firstAccount)
.WithPrompt(Prompt.SelectAccount)
.ExecuteAsync();
}
catch (MsalException msalex)
{
return $"Error Acquiring Token:{Environment.NewLine}{msalex}";
}
}
catch (Exception ex)
{
return $"Error Acquiring Token Silently:{Environment.NewLine}{ex}";
}
return authResult.AccessToken;
}
Continue reading...