-
Notifications
You must be signed in to change notification settings - Fork 9
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
Implementing access policies #76
Comments
Not sure if I'm misunderstanding but what would the advantage of this be over the user simply changing their response in the route handler? The file serving endpoint might benefit from this but I can't think of any other cases, am I missing something? |
The advantage is exactly that: An application using Think of a simple CMS (eg. something like WordPress): The admin backend can be implemented using it's own sub-router on Having some sort of This vastly simplifies the life of a developer implementing such an admin backend as there is one local point where the access policy check is assigned to the I know this because I am running exactly into this issue: Implementing a web application with an admin backend and making sure that every endpoint of that |
I see your point. Why not something like how preflights are currently done then? iirc django allows defining an authentication backend, we could do that with a template (and then some type hiding), which could be registered in the same way preflights are currently. Adding a callable could work I guess, that would let us define preset backends which just overloaded |
Would you care to draft up some code snippets? |
hmm, that could be done at the implementation level. e.g.: struct post_auth {
auto operator()(const malloy::http::request_header<>& h) const -> std::optional<malloy::http::response<>> {
if (h.method() != malloy::http::method::post) return std::nullopt;
/* do some authentication */
}
}; Potentially the return type of this could be the same as for the route handlers, just wrapped in an optional (allowing any type of bodies to be used). I've used It also might be better to have this as something like |
I see the following possibilities:
|
I like 2 personally, it fits best with the existing interface imo. I agree we need some sort of polymorphism on the policies, but I suggest we do the type erasure as an implementation detail. Let the user pass a concept to |
I was hoping you'd say that - I fully agree. Shall we start a branch for this? Do you feel like drafting up the necessary code? :) |
hmm, I wouldn't mind doing it but I was going to work on #55 and #70 so this is gonna have to wait a bit if I'm doing it :p. Also, not sure if we should offer stuff like web tokens out of the box, but I certainly think the API needs to be built with cases like it in mind. I think for starters we should just offer http auth and then have an example using something more complex. |
That's completely fine of course :)
Yeah I fully agree. Having different built-in authentication methods such as JWT is certainly what I'm after. |
Right so the current implementation plan is:
Anything I'm missing before I start implementing this? |
Which scenario do you see this becoming a problem? Reading the body might often not be necessary by a policy implementation.
This one I do see. However, that too should be left to be up to the policy implementation. |
I'm working on this but I've run into a bit of an issue. I need base64 decoding for basic http authentication. I suppose I could implement it myself but I'd rather not, its a real pain and I don't really want to be responsible for testing it and such. OpenSSL has base64 support iirc but that'd make basic http auth support dependent on building with TLS which seems a little weird. We could always just depend on a base64 lib, but casually adding dependencies isn't something I like to make a habit of. I could also just not add the basic http auth support for now, and leave it up to users to create themselves. Thoughts? |
I understand that base64 decoding is required for HTTP basic auth. However, I don't understand why this would be a requirement to implement the policy interface? The idea would be to have an interface as discussed above which allows a user to implement their own policy (or rather: policy access checks). Therefore, it shouldn't be necessary to do the HTTP basic auth checking. For the future it might be nice to have some default policies built into the library. Something like HTTP basic auth might be useful but that would be on top of the interface itself.
Or am I missing / misunderstanding something? |
Most real-life applications have the need of implementing access policies to check whether a client is allowed to perform a certain request. As a basic example: A web application which provides an admin backend. A user should not be able to access any of the endpoints of the admin backend without prior authentication.
Other use cases might include things such as rate limiting (eg. only 100 requests per day).
This should be functionality baked into
malloy
.I think it would be best to have some sort of security-policy-check interface in the
endpoint
class. This might be something as simple as:The router would check the policy constrains on each request. If the check passes (returns
true
), the endpoint handler will be invoked. If the check fails (returnsfalse
), the endpoint handler will not be invoked and the router instead responds with the response provided by the checker. This allows a user of the library to respond in whatever way is sensible for the application.This is just to illustrate the idea roughly. The interface might look differently - it's mainly about functionality at this point.
Especially the cost of doing this via virtual functions might not be desirable in this case.
Also
std::pair<bool, std::optional<response<>>>
is most likely not the way to go. Again: just for illustrating functionality.A
router
should have the capabilities of getting a "default security policy" assigned which will be propagated/used by all endpoints if an endpoint didn't receive a specific policy.@0x00002a thoughts?
The text was updated successfully, but these errors were encountered: