[Stackoverflow] [Progress OpenEdge ABL] MSAL.NET authentication works in C# but not Openedge - "Object reference not set to an instance of an object.'

  • Thread starter Thread starter CephDigital
  • Start date Start date
Status
Not open for further replies.
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 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...
 
Status
Not open for further replies.
Back
Top