What is the best way to notify a user after an access_control rule redirects?
So after quite a bit of research, I found the right way to do this. You'll need to use an Entry Point service and define it in your firewall configuration.
This method will not mess with your default page settings specified in your firewall config for logging in.
The Code
security.yml:
firewalls:
main:
entry_point: entry_point.user_login #or whatever you name your service
pattern: ^/
form_login:
# ...
src/Acme/UserBundle/config/services.yml
services:
entry_point.user_login:
class: Acme\UserBundle\Service\LoginEntryPoint
arguments: [ @router ] #I am going to use this for URL generation since I will be redirecting in my service
src/Acme/UserBundle/Service/LoginEntryPoint.php:
namespace Acme\UserBundle\Service;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface,
Symfony\Component\Security\Core\Exception\AuthenticationException,
Symfony\Component\HttpFoundation\Request,
Symfony\Component\HttpFoundation\RedirectResponse;
/**
* When the user is not authenticated at all (i.e. when the security context has no token yet),
* the firewall's entry point will be called to start() the authentication process.
*/
class LoginEntryPoint implements AuthenticationEntryPointInterface
{
protected $router;
public function __construct($router)
{
$this->router = $router;
}
/*
* This method receives the current Request object and the exception by which the exception
* listener was triggered.
*
* The method should return a Response object
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$session = $request->getSession();
// I am choosing to set a FlashBag message with my own custom message.
// Alternatively, you could use AuthenticationException's generic message
// by calling $authException->getMessage()
$session->getFlashBag()->add('warning', 'You must be logged in to access that page');
return new RedirectResponse($this->router->generate('login'));
}
}
login.html.twig:
{# bootstrap ready for your convenience ;] #}
{% if app.session.flashbag.has('warning') %}
{% for flashMessage in app.session.flashbag.get('warning') %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ flashMessage }}
</div>
{% endfor %}
{% endif %}
Resources:
- AuthenticationEntryPointInterface API
- Entry Points Documentation
- Security Configuration Reference
- How to Customize your Form Login
- Why access_denied_handle doesn't work - thanks to cheesemacfly for tip
Symfony 2 access_controll redirection with params
Yes, it's possible to se the session (of flashbag message) before login without controller involved. It can be done by an Authentication entry point service which is called right after start of authentication process. This Authentication entry point service is a part of firewall configuration as an entry_point
key.
More on this can be found here: http://symfony.com/doc/current/components/security/firewall.html#entry-points
class MyAuthEntryPoint implements AuthenticationEntryPointInterface
{
protected $router;
public function __construct($router) {
$this->router = $router;
}
public function start(Request $request, AuthenticationException $authException = null) {
if ($request->get('_route') == 'submission') {
$session = $request->getSession();
$session->getFlashBag()->add('submissionUserMessage', 'Weclome user from submission!');
//or if you do not want to use flashBag
$session->set('submissionUserMessage', 'Weclome user from submission!');
}
return new RedirectResponse($this->router->generate('login'));
}
}
Service
Is there a way for TWIG to access page's access_control settings in security config file?
i guess there is no way to do this. =(
SF2: Secure route and deny access through exception instead of redirect to login
Take a look at Entry Point option in a firewal - http://symfony.com/doc/current/components/security/firewall.html#entry-points
This question/answer may have the information you need - What is the best way to notify a user after an access_control rule redirects?
Show flashbag message by required user role
You could do it by implementing AccessDeniedHandlerInterface
.
In handle
method you can check request path and add appropriate flash message.
You will have to register your AccessDeniedHandler service in security.yml
:
security:
firewalls:
main:
access_denied_handler: my.access_denied_handler_service_name
Yii2 : Setting Access Control filter to redirect after forbidden
You need to specify denyCallback
to achieve this.
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
//your access rules
],
'denyCallback' => function($rule, $action) {
//redirection here
}
],
];
}
Note that this denyCallback
will be called every time when access is denied. If you want rule-specific denyCallback
e.g. you want different application behavior, then you need to specify it like this:
'rules' => [
//other rules
[
'actions' => ['index'],
'allow' => false,
'roles' => ['@'],
'matchCallback' => function(){
return (Yii::$app->user->identity->ROLE_ID == 2);
},
'denyCallback' => function(){
//redirect here
}
],
],
Here we explicitly disallow access to index action to users with ROLE_ID == 2
and redirecting them.
Related Topics
Connect to PHP Server Using Swift
How to Set a Class Attribute to a Symfony2 Form Input
How to Enable PHP to Work with Postgresql
Issue in Installing PHP7.2-Mcrypt
Create New Xml File and Write Data to It
How to Render Zf2 View Within JSON Response
How to Paginate a Merged Collection in Laravel 5
Getting Relative Path from Absolute Path in PHP
Phpmailer: Reply Using Only "Reply To" Address
Using MySQL Concat() in Where Clause
Curl Error 60: Ssl Certificate in Laravel 5.4
Programmatically Creating New Order in Woocommerce
How to Use Break or Continue Within for Loop in Twig Template
How to Alias a Function in PHP
Email Validation Using Regular Expression in PHP
Create an Order Programmatically with Line Items in Woocommerce 3+
Org.JSON.JSONexception: Value <Br of Type Java.Lang.String Cannot Be Converted to JSONobject