-
Notifications
You must be signed in to change notification settings - Fork 147
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
user authentication #26
Comments
There should also be a solution for mobile devices using the API. The standard web based approach for that is cumbersome. Consider supporting oauth based approach. Tokens handed out should perhaps be revokable through the web interface, but should otherwise be fairly long term expiration, or we need to also implement the token refresh portion. |
This is only the database schema, which I'm adding now in the hopes of freezing schema version 3. There's no way yet to create users, much less actually authenticate.
Some caveats: * it doesn't record the peer IP yet, which makes it harder to verify sessions are valid. This is a little annoying to do in hyper now (see hyperium/hyper#1410). The direct peer might not be what we want right now anyway because there's no TLS support yet (see #27). In the meantime, the sane way to expose Moonfire NVR to the Internet is via a proxy server, and recording the proxy's IP is not useful. Maybe better to interpret a RFC 7239 Forwarded header (and/or the older X-Forwarded-{For,Proto} headers). * it doesn't ever use Secure (https-only) cookies, for a similar reason. It's not safe to use even with a tls proxy until this is fixed. * there's no "moonfire-nvr config" support for inspecting/invalidating sessions yet. * in debug builds, logging in is crazy slow. See libpasta/libpasta#9. Some notes: * I removed the Javascript "no-use-before-defined" lint, as some of the functions form a cycle. * Fixed #20 along the way. I needed to add support for properly returning non-OK HTTP statuses to signal unauthorized and such. * I removed the Access-Control-Allow-Origin header support, which was at odds with the "SameSite=lax" in the cookie header. The "yarn start" method for running a local proxy server accomplishes the same thing as the Access-Control-Allow-Origin support in a more secure manner.
Finally getting there. Some remaining things to do: [moved to first comment to make the issue more skimmable] It'll be a lot more slick once we support built-in https (see #27), but I think if we get those checkboxes ticked we can reasonably say it has auth support. |
I initially chose SameSite=Lax because I thought if a user followed a link to the landing page, the landing page's ajax requests wouldn't send the cookie. But I just did an experiment, and that's not true. Only the initial page load (of a .html file) lacks the cookie. All of its resources and ajax requests send the cookie. I'm not sure about document.cookie accesses, but my cookie is HttpOnly anyway, so it's irrelevant. So no reason to be lax.
The guide is not as quick to follow and amateur-friendly as I'd like. A few things that might improve matters: * complete #27 (built-in https+letsencrypt), so that when not sharing the port, users don't need to use nginx or certbot. * more ubiquitous IPv6 (out of my control but should happen over time) to reduce need to share the port * embed a dynamic DNS client * support UPnP Internet Gateway Device Control Protocol (if common routers have this enabled? probably not for security reasons.) It's progress, though. Enough that I think I'll merge the auth branch into master shortly.
I still don't have all the checkboxes ticked, but it works okay for me, and it shouldn't urgently require schema changes, so I merged it to master. |
Possible enhancement - assign roles to users. At a minimum this would be admin vs user, where an admin can do everything, a user can only view. This would simply need a boolean added to the user table. More fine-grained roles would be nice. This could be achieved with a minimal change to the schema by adding a single column to the user table that holds JSON-encoded data, rather than an extra table. Implementing checks for roles throughout the server code would be most of the work. WRT OAuth - this would be a nice option, especially integrating to external providers like Google or Apple ID, but username/password will need to be available for systems without continuous internet connectivity. |
The message Permissions {
bool view_video = 1;
bool read_camera_configs = 2;
bool update_signals = 3;
} but we can expand as needed. This column is also in the |
Current status: functional but some features missing:
moonfire-nvr config
for usersmoonfire-nvr login
command to make a new session from the CLI (mostly for tools to use)Varies: cookie
or whatever headers to ensure authenticated and unauthenticated requests don't get mixed up in caches.__Host
+SameSite=strict
) when using tls. currently it usesSecure; SameSite=Lax
. (Update: I'm happy with the status quo.)--trust-forward-hdrs
are working together properly.yarn start
) but shouldn't ever be served in production. Maybe restrict via theHost
header.Original issue text:
I want proper user authentication; this (along with some manner of https) is a precondition of exposing Moonfire NVR to the Internet.
As @dolfs said, a temporary measure could be to do basic HTTP with a apache/nginx frontend. But I think it shouldn't be too bad to do a proper built-in thing.
Here's my proposal.
https is a prerequisite. (either built-in or through a proxy.)
You can create/delete/modify users through
moonfire-nvr config
.Creating a session could be simply password-based. Some things that I consider out of scope:
Sessions could simply be a long random number, stored as a hash for the same reason people hash passwords: so a database leak doesn't trivially compromise the credentials. (They should need to edit the database for to gain access, which may be harder to do than getting an old backup, and which leaves more evidence behind.)
Straw man schema:
Typical sessions should probably be represented as cookies with the
HttpOnly
flag set (meaning not accessible to Javascript). If a hit on/api/...
lacks the cookie, it should return a HTTP 401 which the Javascript knows means to redirect the browser to/login
, a simple HTML login form which on success sets the cookie and redirects back.The cookies should also be
secure
(meaning only sent over https, not http).There should also be a way of getting a session id for use by some automated thing. Example: a program that dumps events into the database based on my Elk security system's zone status. Something you can paste into its config file. Better to have separate, high-entropy credentials where possible so you can see what was compromised and disable it independently of the others.
The text was updated successfully, but these errors were encountered: