Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing RestClient or adding helper methods (solves client certificate auth) #24

Closed
mitchcapper opened this issue May 3, 2021 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@mitchcapper
Copy link

New Feature Description

Right now if you use client certificate based auth with HA this library will fail. RestClient easily supports client certificates but it is protected in all the client classes so we can't add certs.

Options I see:

  • Just flip RestClient Client to public:
    protected RestClient Client { get; set; }
  • Add a .Configure(Action client) (not sure is much better)
  • Add specific method for adding client certs (although there may be other client prefs a user would want access to)

I can do a PR with the best action if desired

@mitchcapper mitchcapper added the enhancement New feature or request label May 3, 2021
@qJake
Copy link
Owner

qJake commented May 10, 2021

A configure method would be a good idea - if you have time, give it a shot and I'll take a look. Thanks!

@qJake
Copy link
Owner

qJake commented Aug 14, 2021

Hey @mitchcapper, in v1.6.0 we refactored from RestSharp to just using the built-in HttpClient.

If you're using the ClientFactory, you can access the HttpClient instance directly, after initializing, like so:

ClientFactory.Initialize("https://my.home.assistant/", "eyJ...............");
ClientFactory.Client // This is the underlying HttpClient that is used for API communication, you cannot set it, but you can manipulate its properties.

I think this will work for you, if not please let me know and I will reopen!

@qJake qJake closed this as completed Aug 14, 2021
@mitchcapper
Copy link
Author

Sorry I missed this reply. HttpClient is great however to do the bulk of configuration for it you need to use the HttpClientHandler class and it can only be then passed to the HttpClient constructor, you cannot access it after the fact.

The good news is because of the refactor no modification to this library is needed to do so, we just create our own factory. If you like I can put a PR in to add an overload to the current initialize method that takes a HttpClientHandler to make it easy for others.

 public static class OurClientFactory {
            public static bool IsInitialized { get; internal set; }
            public static HttpClient Client { get; private set; }
            public static void Initialize(Uri instanceAddress, string apiKey, HttpClientHandler handler) {
                Client = new HttpClient(handler) {
                    BaseAddress = instanceAddress,
                    DefaultRequestHeaders =
                    {
                    Authorization = new AuthenticationHeaderValue("Bearer", apiKey),
                    AcceptEncoding =
                    {
                        new StringWithQualityHeaderValue("identity")
                    }
                }
                };
                IsInitialized = true;
            }
            public static void Reset() {
                IsInitialized = false;
                try {
                    Client?.Dispose();
                } catch {
                    // Can't dispose? Oh well.
                }
                Client = null;
            }
            public static void Initialize(string instanceAddress, string apiKey, HttpClientHandler handler) => Initialize(new Uri(instanceAddress), apiKey, handler);
            public static TClient GetClient<TClient>() where TClient : BaseClient => (TClient)Activator.CreateInstance(typeof(TClient), Client);

        }

This then allows you to do something like:
OurClientFactory.Initialize(uri, token, new HttpClientHandler { ClientCertificateOptions= ClientCertificateOption.Automatic });
or
OurClientFactory.Initialize(uri, token, new HttpClientHandler { ClientCertificateOptions= ClientCertificateOption.Manual,ClientCertificates.Add(client_cert) });

LAB02-Admin pushed a commit to LAB02-Admin/HADotNet that referenced this issue Jan 20, 2022
Implements the code from @mitchcapper to allow providing a custom HttpClientHandler:

qJake#24 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants