Redirection after login based on user role - symfony

I am using FosUserBundle in Symfony 3.4. I want to redirect users based on their roles. For example, if the role is Client, the user will be redirected to the clients page. If the user is an Admin, then the user will be redirected to the admin dashboard page. How can I do this with FosUserBundle?

Redirect them both to a controller named indexAction() and Redirect them in the controller based on the role. Something like this:
/**
* #Route("/secure-area", name="homepage")
*/
public function indexAction()
{
if($this->getUser()->hasRole('ROLE_ADMIN'))
return $this->redirect($this->generateUrl('admin_area'));
elseif($this->getUser()->hasRole('ROLE_USER'))
return $this->redirect($this->generateUrl('client_area'));
throw new \Exception(AccessDeniedException::class);
}
EDIT:
You should set the default_target_path to the path above

Related

Authorization in ASP.Net Core

I am developing an admin dashboard panel, I have created an intro page for the dashboard which users can log in there
I have four types of user, Admin, SiteManager, PI, and EndUser
After successfully login into the dashboard!
I also Use an Admin Area for something named "Content Management" which is only accessible for the Admin
but when I try to navigate to this content management, it redirects me to the login ( Authorization redirect loops), but the user is already logged in (because I put If condition if the user role is Admin this content management shows)
I am using the individual authentification and scaffold the identity
ASP .Net core 3.1
I don't know how to solve this redirect issue!
in below I put some snip code
[Authorize(Roles =SD.SuperAdmin)]
[Area("Admin")]
public class HMController : Controller
{
private readonly ApplicationDbContext _context;
public HMController(ApplicationDbContext context)
{
_context = context;
}
note: the proposed if the condition is in _layout page
and the Admin Area uses another layout(not _layout)!
Also, I have already checked the Sqlserver the roles and the user are created and functional!
the _layout code:
#if (User.IsInRole(SD.SuperAdmin) || User.IsInRole(SD.ManagerUser))
{
...
#if (User.IsInRole(SD.SuperAdmin))
{
..
}
...
}
If you check for logged user at Login Action and there route user by role.
You solve this problem
if (User.Identity.IsAuthenticated)
{
if (GetUserType() == "Admin")
return Redirect("Admin/Index");
else if (GetUserType() == "Context")
return Redirect("Context/Index");
}
For example:
If admin logged system then if admin click not authorized page then redirect Account/Login.
Account/Login page is check to user login
If user logged then redirect user homepage

Login and set remember_me cookie after user registration in Symfony

I have a controller action which processes user's data, registers the user, logs them in and redirects them to another controller's action. However I am unable to get the "remember_me" cookie set.
On a successful registration, the controller will obtain the $user object and then pass this onto the authenticateUserAndHandleSuccess() method of the GuardAuthenticatorHandler which is part Symfony's Security Bundle.
use Symfony\Component\HttpFoundation\Request;
use App\Security\LoginFormAuthenticator;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
public function register(Request $request, LoginFormAuthenticator $authenticator, GuardAuthenticatorHandler $guardHandler) {
// do something... and get $user object
return $guardHandler->authenticateUserAndHandleSuccess(
$user,
$request,
$authenticator,
'main'
);
}
What this does is to automatically login the user. However, it does not set the remember_me cookie which is presently working and used in the login form.
From the security.yaml
remember_me:
secret: '%kernel.secret%'
lifetime: 2592000 # 1 month in seconds
path: /
remember_me_parameter: login_form[_remember_me]
How could the controller be changed to also set the "remember_me" cookie?
I don't know if this is a good idea to set remember_me during registration but if you really need it just check onLoginSuccess method of TokenBasedRememberMeServices which is executed during login process when proper remember me parameter is being send - it's just about setting proper cookie.

403 "rest_forbidden" error in WordPress REST API (but only for settings)?

i got all API from WordPress except settings (/wp/v2/settings). its returning rest_forbidden error
{
"code": "rest_forbidden",
"message": "Sorry, you are not allowed to do that.",
"data": {
"status": 403
}
}
Your user does not have the correct permissions to access the data at that route. Out of the box the /settings/ route requires the manage_options permission (see the get_item_permissions_check method).
// found in WP Core class-wp-rest-settings-controller.php
/**
* Checks if a given request has access to read and manage settings.
*
* #since 4.7.0
*
* #param WP_REST_Request $request Full details about the request.
* #return bool True if the request has read access for the item, otherwise false.
*/
public function get_item_permissions_check( $request ) {
return current_user_can( 'manage_options' );
}
What user is associated with the API credentials?
The settings endpoint needs the user to have manage_options permission; if you're using a custom role, you can add it with
"manage_options" => true;
Otherwise just make the user Administrator role.
If somebody has an issue then try installing this plugin: https://wordpress.org/plugins/application-passwords/
Generate an application password from your profile and use that with basic auth, your username will be the same as WordPress username or email and the password will be new generated password.
You may also need to add HTTP header rewrite rule in your .htaccess file, for that please follow: https://github.com/WordPress/application-passwords/wiki/Basic-Authorization-Header----Missing

PreExecute() function in symfony2

I developed an application using symfony2, I want to know how to write preExecute() function symfony2 for following case:
when I log-in into the system; it redirect me on user profile section when I log-out from same screen, It killed session and redirect me on login screen, but when I hit browser's back button then it will redirect me on profile screen, which shows me all user information but when I click for next process from same screen then I redirect me on login page.
I just want to add preExecute function like symfony1.4 for this case, so I checked session and if it is null then it will redirect me on login page if I hit browser's back button when I alrady log-out from the system.
I already added following code in profileController.php files,
public function indexAction() {
$session = $this->get('request')->getSession();
$userId = $session->get('id');
if ($userId == 0 || $userId == '') {
return $this->redirect($this->generateUrl('_security_login'));
} else {
//my code
}
}
//logout action
public function dologoutAction(){
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
$this->container->get('request')->getSession('session')->clear();
return $this->redirect($this->generateUrl('_security_login'));
}
if there is any other way to handle this case then please help me for the same.
Thank you.
Just require the ROLE_USER role on the profile action and the firewall will do the redirect-to-the-login-form-and-then-redirect-back stuff:
/**
* #Secure("ROLE_USER")
*/
public function profileAction()
{
// ...
}
For more information read the Security chapter of the Symfony book.

Symfony2: how to log user out manually in controller?

i would like to do something like that in controller to log user out:
$user = $this->get('security.context')->getToken()->getUser();
$user->logOut();
Logout in Symfony2 is handled by so called logout handler which is just a lister that is executed when URL match pattern from security configuration, ie. if URL is let's say /logout then this listener is executed. There are two build-in logout handlers:
CookieClearingLogoutHandler which simply clears all cookies.
SessionLogoutHandler which invalidates the session
All you have to do is the very same the last one does. You can achieve it by simply calling:
Legacy Symfony
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
Symfony 2.6
$this->get('security.token_storage')->setToken(null);
$this->get('request')->getSession()->invalidate();
Warning
This will only work when remember me functionality is disabled. In other case, user will be logged in back again by means of a remember me cookie with the next request.
Please consider the extended solution if you are using remember me functionality: https://stackoverflow.com/a/28828377/1056679
Invalidating the user's session might cause some unwanted results. Symfony's firewall has a listener that always checks and refreshes the user's token. You could just do a redirect to the default logout route that you have specified in your firewall.yml (or security.yaml)
In Controller you can do this:
$this->redirect($this->generateUrl('your_logout_url'));
If you don't know the name of the logout route (your_logout_url), you can get it from the Symfony console by using this command:
app/console router:match /logout
Or newer Symfony versions:
bin/console router:match /logout
:)
We have to set user as an anonymous user when logging out. Then we can use
$token->getUser()->getRoles(); in controller or {% if is_granted('ROLE_USER') %} in the twig template.
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
...
//$providerKey = $this->container->getParameter('fos_user.firewall_name');
$token = new AnonymousToken($providerKey, 'anon.');
$this->get('security.context')->setToken($token);
$this->get('request')->getSession()->invalidate();
If rememberme functionality is enabled for your site you should also clean rememberme cookie:
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
$response = new RedirectResponse($this->generateUrl('dn_send_me_the_bundle_confirm', array(
'token' => $token
)));
// Clearing the cookies.
$cookieNames = [
$this->container->getParameter('session.name'),
$this->container->getParameter('session.remember_me.name'),
];
foreach ($cookieNames as $cookieName) {
$response->headers->clearCookie($cookieName);
}
In Symfony 4/5 this is just enough to remove user:
/**
* #var TokenStorageInterface $token_storage
*/
private TokenStorageInterface $token_storage;
/**
* Will force logout from system
*/
public function logoutCurrentlyLoggedInUser()
{
$this->token_storage->setToken(null);
}
Now You can create a method to use it later to check if user is logged in:
class Application extends AbstractController {...
/**
* Returns currently logged in user
* #return object|UserInterface|null
*/
public function getCurrentlyLoggedInUser()
{
return $this->getUser();
}
In case you are using symfony 4.x (I haven't tested other versions, so it still might work), you may want to use the internal logout handler of symfony (highly recommended, as it will take care of everything for you in a clean way, cookies and all). You don't need to write too much code for that either, you can simply emulate a logout request:
... // Some code, that leads you to force logout the user
// Emulating logout request
$logoutPath = $this->container->get('router')->generate('app_logout');
$logoutRequest = Request::create($logoutPath);
$logoutResponse = $this->container->get('http_kernel')->handle($logoutRequest);
// User is logged out now
... // Stuff to do after logging out, eg returning response
This will make symfony do the request response flow, thus it will call the logout handler internally. This method allows you to proceed to further custom code. Otherwise, if you invoked only the logout listener here, you would have to return the usual logout response, that now is in $logoutResponse. Optionally, if you want to return it, you would also simply:
return $logoutResponse;
The proposed solutions didn't work for me in Symfony 5.3.
It should be something as basic as
session_start();
session_destroy();
So I did this way:
$this->get('session')->start();
$this->get('session')->invalidate();
This will terminate the PHP Session, which is the way most of sessions work in Symfony.

Resources