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

Universal authentication provider for external services #19975

Closed
bob1de opened this issue Jan 11, 2019 · 18 comments
Closed

Universal authentication provider for external services #19975

bob1de opened this issue Jan 11, 2019 · 18 comments
Labels

Comments

@bob1de
Copy link
Contributor

bob1de commented Jan 11, 2019

Hi,

I wrote an universal auth provider that calls a user-defined program, passing username and password via environment and then grants access on returncode 0. It works similar to the auth-user-pass-verify option of OpenVPN. Even the visible name for the user can be written to stdout by the external program and is then added to HA's database. It's all fully async, of course.

I use it with a very simple shell script that uses curl to do LDAP authentication (including group membership checks), works like a charm, even in the official Docker image, thanks to curl being available there.

It could be used for all kinds of authentication mechanisms, like PAM, flat databases, etc.

If you'd appreciate it, I could write the docs for it and submit a PR.

Best regards
Robert

@rohankapoorcom
Copy link
Member

I would be interested in this (would love to see what you've got). I've been thinking about making a fullly integrated LDAP provider and this would be a good way to see how to go about this.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Yes, I was thinking about a native LDAP provider as well, but find this a lot more flexible. I just extended the companion script to support both curl and ldapsearch.

Docs aren't written yet, but the code is almost ready to share I think.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

And, at least for me, I don't see a reason to reinvent the wheel. With the generic approach, I rely on well-known LDAP clients and get this working with almost no custom code.

@balloob
Copy link
Member

balloob commented Jan 11, 2019

Would curl be the right interface or should it just be a "command line auth provider" ?

@rohankapoorcom
Copy link
Member

Yeah, I would want to integrate groups with home assistant groups, assuming this allows that, it would be sufficient for my needs.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

For now, it can only grant or revoke access based on custom LDAP filters, including groups, but isn't integrated with HA groups. The developer docs don't seem to provide information about how to do that. Any user is just placed in the system-admin group.

@balloob
Copy link
Member

balloob commented Jan 11, 2019

Yeah, that part is still under construction.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

@balloob What I did is a generic one, just executing a configurable program, nothing specific to curl.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

@balloob Good to know.

I included a mechanism to pass custom fields from the program back to HA via stdout, which is currently used only for name, but as soon as an official interface for setting groups is available, that could easily be extended to allow dynamic group placement as well.

@balloob
Copy link
Member

balloob commented Jan 11, 2019

What would be the best way to get data back, print JSON ? Or would we provide a value_template and allow users to hack stuff with Jinja2 ?

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Hmm, it's very simple right now, just lines of the form:

KEY=VALUE

like the output of the env command.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Ah, you talk about making the complete login flow dynamic as well, not just fields to write to the user account, right?

@balloob
Copy link
Member

balloob commented Jan 11, 2019

I was thinking just name and groups. Don't want to go too crazy and no one will use it as it's too complicated.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Yes, my thoughts.

But then, I think, a simple KEY=VALUE list would be enough, or what do you think?

@balloob
Copy link
Member

balloob commented Jan 11, 2019

Yeah, that will work.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Ok, then let me sanitize the code and make the PR, we could then discuss the details. Docs will be done when the API is finalized.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Alright, there you go. Maybe we should continue discussion in the PR thread.

@bob1de
Copy link
Contributor Author

bob1de commented Jan 11, 2019

Oh seriously, what's going on with GitHub... 404, 405, 504 errors all day long.

@cgarwood cgarwood added the auth label Jan 12, 2019
balloob pushed a commit that referenced this issue Feb 7, 2019
…g a command (#19985)

* Added external auth provider that calls a configurable program

Closes #19975

* Raise proper InvalidAuth exception on OSError during program execution

* Changed name of external auth provider to command_line

* Renamed program config option to command in command_line auth provider

* Made meta variable parsing in command_line auth provider optional

* Added tests for command_line auth provider

* Fixed indentation

* Suppressed wrong pylint warning

* Fixed linting

* Added test for command line auth provider login flow

* Log error when user fails authentication

* Use %r formatter instead of explicit repr()

* Mix all used names of typing module into module namespace

I consider this nasty and bad coding style, but was requested by
@awarecan for consistency with the remaining codebase.

* Small code style change

* Strip usernames with command_line auth provider
bachya pushed a commit to bachya/home-assistant that referenced this issue Feb 7, 2019
…g a command (home-assistant#19985)

* Added external auth provider that calls a configurable program

Closes home-assistant#19975

* Raise proper InvalidAuth exception on OSError during program execution

* Changed name of external auth provider to command_line

* Renamed program config option to command in command_line auth provider

* Made meta variable parsing in command_line auth provider optional

* Added tests for command_line auth provider

* Fixed indentation

* Suppressed wrong pylint warning

* Fixed linting

* Added test for command line auth provider login flow

* Log error when user fails authentication

* Use %r formatter instead of explicit repr()

* Mix all used names of typing module into module namespace

I consider this nasty and bad coding style, but was requested by
@awarecan for consistency with the remaining codebase.

* Small code style change

* Strip usernames with command_line auth provider
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants