0

My application makes calls out to a bunch of different external API classes. To facilitate this, I have a class for each external API to be called, all of which inherit from a base class which starts like this:

public abstract class ApiBase : 
{
    protected static HttpClient client = new HttpClient();
    protected EntityFrameWorkCredentialObject credential;

    public bool AccountSupported(int accountId)
    {
        using (var context = DBProvider.GetTransientEntityContext())
        {
            credential = context.EntityFrameWorkCredentialObject
                            .Where(x => x.AccountId == accountId.FirstOrDefault();
        }

        return credential != null;
    }
}

These objects are created via a factory class, through which it is impossible to get an instance of an object without first checking AccountSupported. So any instance of a class which inherits this base will have its credential populated.

Most of these APIs are either public or accept a key as part of the request. However, we now have to deal with a new API which requires a network credential. The documentation for HttpClient says this has to be passed into the object when it's created.

using (var handler = new HttpClientHandler { Credentials = ... })
using (var client = new HttpClient(handler))
{
    var result = await client.GetAsync(...);
}

That's obviously going to cause problems for the way my object is built, since it creates an HttpClient when it's instantiated, and relies on getting the credentials after the fact.

Is there no way to set the credentials on an existing object, or another way out of this without doing a ton of refactoring?

3
  • 1
    I would try something like this. stackoverflow.com/questions/10077237/… Commented Nov 28, 2018 at 15:49
  • 1
    You could try managing the handler upfront along with a CredentialCache Class. based on the request endpoint you decide if to enable UseDefaultCredentials Commented Nov 28, 2018 at 15:49
  • 1
    @RyanSchlueter Sweet, that did the job, thanks Commented Nov 28, 2018 at 15:58

1 Answer 1

3

All that the credentials thing does is to add the required authentication header to the httpclient requests.

You can always go ahead and add authentication headers manually by setting default request headers:

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer","Token");
client.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Basic",
    Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
        string.Format("{0}:{1}", "yourusername", "yourpwd"))));
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks - question turns out to be a dupe, but this is the right answer and deserves and upvote
thanks always here to help :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.