Alternatives to isGranted in Symfony2 - php

While testing roles in my application I found the function isGranted of the SecurityContext. It works great but now I need to check the roles of a user that is not the current user so isGranted doesn't work for me.
I've been looking and I found the function hasRole of the user, the problem is that this function doesn't look in the hierarchy tree of Symfony and it just looks in the roles assigned to the user.
So, Is there a function that looks for a role of a user looking in the hierarchy tree like isGranted do for the current user?
EDIT
I found this solution:
How to use the AccessDecisionManager in Symfony2 for authorization of arbitrary users?
I implemented it and it works, the problem is that it needs the ContainerBuilder and I would prefer a different approach.
Any Idea?

Basically AFAIK SecurityContext work with Symfony\Component\Security\Core\Authentication\Token\TokenInterface from where can fetch current user using getUser method.
If user token is not authenticated then isGranted trying authenticate user token first and then use class called AccessDecisionManager which basically iterate over voters objects and call them (and can use different strategies for that) One of called voters is RoleHierarchyVoter which use Symfony\Component\Security\Core\Role\RoleHierarchy.
So answer to your question:
I think that is no such function like isGranted for other users (or do not know about any), but you can write own service which allow to that using security.role_hierarchy (just notice that is private service).
BTW hasRole probably should be sufficient most of the time, so maybe you should think about what do you want to do ;)

Related

Can someone explain what this code does in laravel

I think i have a rough idea of what a guard does. for some reason there's not really much write-up about it online. I saw this line of code in someones middleware
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
and i don't understand what it does. i understand that there two types of inbuilt guards-web and api and web is the default guard. What does the "Guard" inside the construct do? and how does the $auth variable come into play?.
here's the pic of the full code
The Guard class is used for authentication i.e. logging a user in, checking to see if there is an authenticated user, retrieving the authenticated user, logging them out etc.
I'd say the most common way to access this information (going off the docs and various tutorials) is by using either the Auth Facade or the auth() helper function. With either approach you will have access to the same methods e.g.
auth()->user() or Auth::user() will return the current authenticated user.
auth()->id() or Auth::id() will return the current authenticated user's id.
auth()->check() or Auth::check() will tell you if the current user is logged in or not.
etc.
In either case (using auth()-> or Auth::) you're going to accessing methods on the Guard class.
Laravel also has something called the Service Container which is a way for you to be able to have dependency injection. This is essentially where you can get an instance of a class automatically without having to do something like new ClassName(). This might not seem like a big deal at first but if you have a class that needs to be passed different variable and classes to its constructor you can set this up in the container so you don't have to worry about it. Another benefit might be that you want to use the same instance of a class rather than creating a new one each time which is something that can be done with the container as well.
Now, some people prefer to use dependency injection instead of using Facades or helper functions (see here for more information). With the case in your example you're injecting the Guard class so that you can access it as a property on the class rather than using the Facade or helper function. There isn't more to it than that.

Where to place the authentication logic in Laravel?

I have used this tutorial for creating my user login in Laravel: Laravel Authentication Essentials. So I have a SessionController that contains the methods create, store and destroy, for showing the form, logging in and out respectively.
But there is no model in this tutorial, the validation and Auth::attempt is in the controller. And that doesn't feel right. I can not create a Session model, since the Session class already exists.
Should I put the login/out logic in the User model, or is there another way to do this that complies with the MVC architectural pattern?
First, remember (or know) that you can change everything in Laravel. If you need a Session model using a sessions table, go to app/config/session.php and change the Laravel sessions table to laravel_sessions:
'table' => 'laravel_sessions',
People are doing things differently these days, methods are improving on a daily basis and the way you do your code must be confortable to you. If you feel it is not right the way you are seeing people doing it, change it, Laravel give you the power to change and do things your way. And if you feel you just found a better way of doing it, share it.
This is a 2013 video and today Jeffrey is doing authentication in a completly different way. Sign up for a Laracasts account and take the full Build a Larabook video series to see how he's doing it now.
There's no Session model in this tutorial because he's not storing sessions (successful logins) in a sessions table.
In the tutorial he never touches the User model, so there is no login in the user model. The only thing he's using to do authentication is Auth::attempt(), a Laravel facade method which uses internally the user model (M), to find a user and check if the password matches. He's working with a Session controller (C) and everything related to login (or sign in) and showing login views (V) is done inside that particular controller.
If it is easier to you, you can rename SessionsController to LoginController, I, myself, don't really like the Sessions name for login, but that's a matter of taste not code correctness.
That being said I don't see an MVC (or whatever name people like to call it this week) problem in that video.
EDIT Answering the comment:
The purpose of the model is towards data, no data, no model. In the context of Laravel and a database management system, yes, no table, no model. In the context, for instance, of a client-server API, your server API (Laravel, Rails...) will provide data for your client model (Angular, EmberJS...), so, there will be no table directly related to the client model, but still a model.
But in that particular case you are accessing a model, the user model, via a service, the Authentication service.

Laravel: Know What to Implement in model

I am just about three days old in laravel, yesterday I tried creating an authentications system using eloquent, so without looking I deleted the default User model, and then I tried creating my own from what I had read from the documentation. After setting up every thing as I had studied and understood, I tried running my app, but whenever I enter the correct username and password I get this error
Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials()
must be an instance of Illuminate\Auth\UserInterface, instance of User given, called in dir
I did not know what the EloquentUserProvider was or where it was even coming from. My original model looked like this
class User extends Eloquent {}
I battled with this error for the whole day (no exaggeration), But today I found out from this SO Can't authenticate user in laravel that it was because I had not implemented some interface, so they linked me to https://github.com/laravel/laravel/blob/master/app/models/User.php where I copied the default model I initially deleted.
I used the documentation almost through out my learning process, and no where in the documention for authentication and for eloquent did they mention that we are suppose to implement these interface for us to be able to use Auth::attempt() method, my question now is how then do we (newbies) know what to implement and what not to implement, or what any of these interfaces even do.
This is simple. It's a laravel's requirement. The User model is generated by default for you. If you do not need to implement the interface's methods, just add them empty in your User class.
And of course, in your case, what to extend or implement will be shown as errors on startup. Reading them carefully can give you all the asnwers.
Also, if you want to use different User Authentication features, or extend the existing ones, you can look some info here in the docs

Symfony2 limit access user

I want to limit user access only for admin on some routers and I want to know how is it best practice to do that, is it possible from routing (example after call my function from controller I want to call one function who say true if I'm admin or false if not) or need for all function call my function first for verify.
I was read the documentation symfony2 but no specific noting if is possible.
Since you need to limit access on specific routes, you can do so with Symfony's Access Control in your security.yml. Read the docs in order to achieve this.
See http://symfony.com/doc/current/book/security.html#book-security-securing-controller in the Symfony2 documentation. You need to access the security.context service and return the proper value based on the user's roles.

Symfony2 HttpKernel Before and after methods in controllers (Kohana Style)

I know that this problem was discussed so many times but I had found some solution and I'm not sure if it is the best and the most efficient approach.
My problem: I'm using fosuserbundle to handle user authentication and I would also like to prevent displaying of login, password resetting, etc. form for logged in users. Below I put some approaches:
The first one (which has been already implemented) based on the kernel events, there is a code
https://gist.github.com/walmen/871c13014b80c6a3d05d
The second approach which was mentioned by my colleague based on the method overloading (removing listeners and duplicate code in the each method which has some logic which shouldn't be displayed for logged in users)
Write custom annotation, i.e. #RequireAnonymous
As I mentioned before, I've already implemented the first approach but I'm not sure if it is the best and the most efficient solution (this listener would be called for each request - it is not too heavy load for application? How listeners affect the application, if they?).
The second approach is the easiest one of course but...code duplication doesn't sound really nice.
The last one might be the best but If we take a look on this example https://gist.github.com/cystbear/1391850 we will see that there is also problem with calling event during any controller call.
Any advice or other ideas with good arguments and explanation?
If I'm understanding you correctly, you can use the third approach with the JMSSecurityExtraBundle which is included with Symfony Standard.
On the action's you want to exclude from authenticated users you can do like so:
/**
* #Secure(roles="IS_AUTHENTICATED_ANONYMOUSLY")
*/
public function fooAction()
{
// stuff...
}
This ensures that the user requesting the specific path is not authenticated.
#Ramon not really because every user has the role IS_AUTHENTICATED_ANONYMOUSLY, even the authenticated ones.
What is more we don't want to throw an exception like "Access denied" or something but we want to 'hide' those pages thanks to the redirection.
What do you think about this https://github.com/FriendsOfSymfony/FOSUserBundle/issues/996#issuecomment-14812806 ?

Categories