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

[Security] Make firewall more extensible #22260

Closed
kleijnweb opened this issue Apr 3, 2017 · 9 comments
Closed

[Security] Make firewall more extensible #22260

kleijnweb opened this issue Apr 3, 2017 · 9 comments

Comments

@kleijnweb
Copy link

kleijnweb commented Apr 3, 2017

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no
Symfony version 2.8+

As long as you are only interested in authentication, adding behavior to the firewall works fine. But if you need your listener to be executed after the AnonymousAuthenticationListener, you're gonna get a cold shower.

What would be needed is new items in SecurityExtension::$listenerPositions for the listeners that are now added without using that (I counted 3 real quick), add all the listeners in a single loop. Then it would also be nice to allow NULL for the first value in the tuple returned by SecurityFactoryInterface::create(), I now have to work around that by using a provider that always returns FALSE when support() is invoked because it actually is interpreted as a service ID of "" (which could also be considered a bug).

I'll gladly cook up a PR if it has any chance of getting merged.

kleijnweb added a commit to kleijnweb/symfony that referenced this issue Apr 4, 2017
kleijnweb added a commit to kleijnweb/symfony that referenced this issue Apr 4, 2017
@linaori
Copy link
Contributor

linaori commented Apr 4, 2017

What's your use-case?

Reading your PR, I think it's good to have the anon functionality work the same as the rest, but I don't think the firewall is the place to couple some logic. Why not use one of the existing events for this?

@kleijnweb
Copy link
Author

@iltar Can you clarify "couple some logic"?

I think the firewall is an excellent place to hook in some request-based authorization, and in fact that is exactly what AccessListener does. But when you want something custom not possible with access_control, but still request based (eg REST semantics based ACL, just an example), you have to do it outside of the firewall and you lose some benefits, not to mention consistency with the standard AccessListener.

@linaori
Copy link
Contributor

linaori commented Apr 4, 2017

You're coupling authorization logic to authentication. The firewall is only authentication. You're coupling authorization logic with authentication.

But when you want something custom not possible with access_control, but still request based (eg REST semantics based ACL, just an example), you have to do it outside of the firewall and you lose some benefits, not to mention consistency with the standard AccessListener.

What's something custom that's not possible with access_control?

@kleijnweb
Copy link
Author

The firewall is only authentication.

Uhm no, that is simply not true. Authorization of requests is handled by the firewall as well, not to mention some other stuff like impersonation and identity persistence across requests.

@linaori
Copy link
Contributor

linaori commented Apr 4, 2017

Uhm no, that is simply not true.

In your PR you call it the SomePostAuthenticationFactory and if I understand you correctly, that's where you want to perform authorization, not authentication.

The firewall has some options that are related to authorization, like access denied handlers, which can be used to re-authenticate as someone who does have enough access. What I see here, is a PR that adds authorization to the authentication configuration.

Now my question still stands:

What's something custom that's not possible with access_control?

Maybe there's another solution.

@kleijnweb
Copy link
Author

Correct, that is in an example of doing something "post-authentication", in this case specifically, authorization.

I think I understand what you mean now, when you say "the firewall", you mean the firewalls as represented in the user configuration? What I mean when I say "the firewall" is the actual firewall object and its listeners.

That PR is just some low hanging fruit, really the whole SecurityExtenstion needs a pretty big refactoring, moving logic to factories for the existing listeners like I did for anon so that alternate implementations are possible. I've started doing that but it is a very slow process.

As far as the configuration goes, I don't think it is a "bad thing" to expose config options for a factual (code-wise) situation. Especially since writing these kinds of plugins would require a pretty intimate knowledge of how the firewall actually works and thus fall in the "advanced use" category.

And I realize using access_control is sufficient for most use cases, but not for all. And yes, one (assuming RBAC) could hook into kernel requests to add rules to AccessMap. Or I could do it all outside of the firewall, but stuff like access_denied_handler won't work, which is a shame. And none of that is any help when I want to customize other firewall behavior like user impersonation.

Bottom line is, there is too much hardwired stuff in the listener chain in the firewall. I don't mean to be negative about it, I'm trying to do something about it :)

@linaori
Copy link
Contributor

linaori commented Apr 4, 2017

Actually, I think that access_control is sufficient. You can solve a lot with a voter and a custom attribute. The problem here is that it's called "roles" in the access_control, so it's extremely confusing. Additionally, you could also use a user-checker for user-related checks:

http://symfony.com/doc/current/security/user_checkers.html

I fully agree with refactor you did for the anon. listener, I was not aware this was hard-coded in the first place.

Or I could do it all outside of the firewall, but stuff like access_denied_handler won't work, which is a shame.

The access denied handler is triggered upon throwing an AccessDeniedException, such as the @Security does.

http://symfony.com/doc/current/security/access_denied_handler.html

Bottom line is, there is too much hardwired stuff in the listener chain in the firewall. I don't mean to be negative about it, I'm trying to do something about it :)

Trying is always a good thing. For your PR, I would personally split the authorization (or post auth listener) from the anon. part.

@kleijnweb
Copy link
Author

I don't agree (obviously :P) but if that is what it takes to get the PR merged I will make the adjustments and probably submit a PR with more extensive improvements later.

@kleijnweb
Copy link
Author

Refactoring all the listeners to use factories and sorting positions is even more involved than I already suspected. But I am willing to do it, if there's interest.

@fabpot fabpot closed this as completed Jul 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants