pio*_*kkr 25 security authentication extending symfony
我想在身份验证成功后更改默认身份验证过程.我创建了一个在身份验证成功之后和重定向之前调用的服务.
namespace Pkr\BlogUserBundle\Handler;
use Doctrine\ORM\EntityManager;
use Pkr\BlogUserBundle\Service\Encoder\WpTransitionalEncoder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\Response;
class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
{
protected $entityManager = null;
protected $logger = null;
protected $encoder = null;
public function __construct(EntityManager $entityManager, LoggerInterface $logger, WpTransitionalEncoder $encoder)
{
$this->entityManager = $entityManager;
$this->logger = $logger;
$this->encoder = $encoder;
}
/**
* This is called when an interactive authentication attempt succeeds. This
* is called by authentication listeners inheriting from
* AbstractAuthenticationListener.
*
* @param Request $request
* @param TokenInterface $token
*
* @return Response never null
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$user = $token->getUser();
$newPass = $request->get('_password');
$user->setUserPassword($this->encoder->encodePassword($newPass, null));
$this->entityManager->persist($user);
$this->entityManager->flush();
//do redirect
}
}
Run Code Online (Sandbox Code Playgroud)
在services.yml中
services:
pkr_blog_user.wp_transitional_encoder:
class: "%pkr_blog_user.wp_transitional_encoder.class%"
arguments:
cost: "%pkr_blog_user.wp_transitional_encoder.cost%"
logger: @logger
pkr_blog_user.login_success_handler:
class: Pkr\BlogUserBundle\Handler\AuthenticationSuccessHandler
arguments:
entity_manager: @doctrine.orm.entity_manager
logger: @logger
encoder: @pkr_blog_user.wp_transitional_encoder
Run Code Online (Sandbox Code Playgroud)
并在security.yml
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: pkr_blog_admin_login
check_path: pkr_blog_admin_login_check
success_handler: pkr_blog_user.login_success_handler
logout:
path: pkr_blog_admin_logout
target: /
Run Code Online (Sandbox Code Playgroud)
我正在尝试实现的只是改变默认行为,所以我想为什么不扩展DefaultAuthenticationSuccessHandler,添加一些东西onSuccessHandler()和调用parent::onSucessHandler().我试过,问题是我不知道如何将安全参数(在security.yml中设置)添加到我的扩展类构造函数中.DefaultAuthenticationSuccessHandler使用HttpUtils和$ options数组:
/**
* Constructor.
*
* @param HttpUtils $httpUtils
* @param array $options Options for processing a successful authentication attempt.
*/
public function __construct(HttpUtils $httpUtils, array $options)
{
$this->httpUtils = $httpUtils;
$this->options = array_merge(array(
'always_use_default_target_path' => false,
'default_target_path' => '/',
'login_path' => '/login',
'target_path_parameter' => '_target_path',
'use_referer' => false,
), $options);
}
Run Code Online (Sandbox Code Playgroud)
所以我的扩展类构造函数应该如下所示:
// class extends DefaultAuthenticationSuccessHandler
protected $entityManager = null;
protected $logger = null;
protected $encoder = null;
public function __construct(HttpUtils $httpUtils, array $options, EntityManager $entityManager, LoggerInterface $logger, WpTransitionalEncoder $encoder)
{
$this->entityManager = $entityManager;
$this->logger = $logger;
$this->encoder = $encoder;
}
Run Code Online (Sandbox Code Playgroud)
将HttpUtils服务添加到我的中很容易services.yml,但是选项参数是什么?
services:
pkr_blog_user.wp_transitional_encoder:
class: "%pkr_blog_user.wp_transitional_encoder.class%"
arguments:
cost: "%pkr_blog_user.wp_transitional_encoder.cost%"
logger: @logger
pkr_blog_user.login_success_handler:
class: Pkr\BlogUserBundle\Handler\AuthenticationSuccessHandler
arguments:
httputils: @security.http_utils
options: [] #WHAT TO ADD HERE ?
entity_manager: @doctrine.orm.entity_manager
logger: @logger
encoder: @pkr_blog_user.wp_transitional_encoder
Run Code Online (Sandbox Code Playgroud)
dmc*_*abe 44
如果您只为应用程序定义了一个成功/失败处理程序,那么执行此操作的方法会稍微简单一些.而不是为success_handler和定义新服务failure_handler,您可以覆盖security.authentication.success_handler而security.authentication.failure_handler不是.
例:
services.yml
services:
security.authentication.success_handler:
class: StatSidekick\UserBundle\Handler\AuthenticationSuccessHandler
arguments: ["@security.http_utils", {}]
tags:
- { name: 'monolog.logger', channel: 'security' }
security.authentication.failure_handler:
class: StatSidekick\UserBundle\Handler\AuthenticationFailureHandler
arguments: ["@http_kernel", "@security.http_utils", {}, "@logger"]
tags:
- { name: 'monolog.logger', channel: 'security' }
Run Code Online (Sandbox Code Playgroud)
AuthenticationSuccessHandler.php
<?php
namespace StatSidekick\UserBundle\Handler;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Http\HttpUtils;
class AuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler {
public function __construct( HttpUtils $httpUtils, array $options ) {
parent::__construct( $httpUtils, $options );
}
public function onAuthenticationSuccess( Request $request, TokenInterface $token ) {
if( $request->isXmlHttpRequest() ) {
$response = new JsonResponse( array( 'success' => true, 'username' => $token->getUsername() ) );
} else {
$response = parent::onAuthenticationSuccess( $request, $token );
}
return $response;
}
}
Run Code Online (Sandbox Code Playgroud)
AuthenticationFailureHandler.php
<?php
namespace StatSidekick\UserBundle\Handler;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\Security\Http\HttpUtils;
class AuthenticationFailureHandler extends DefaultAuthenticationFailureHandler {
public function __construct( HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null ) {
parent::__construct( $httpKernel, $httpUtils, $options, $logger );
}
public function onAuthenticationFailure( Request $request, AuthenticationException $exception ) {
if( $request->isXmlHttpRequest() ) {
$response = new JsonResponse( array( 'success' => false, 'message' => $exception->getMessage() ) );
} else {
$response = parent::onAuthenticationFailure( $request, $exception );
}
return $response;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我只是尝试设置一些内容,以便在尝试使用AJAX进行身份验证时获得JSON响应,但原理是相同的.
这种方法的好处是,无需任何额外的工作,通常传递给默认处理程序的所有选项都应该正确注入.这是因为在框架中如何设置SecurityBundle\DependencyInjection\Security\Factory:
protected function createAuthenticationSuccessHandler($container, $id, $config)
{
...
$successHandler = $container->setDefinition($successHandlerId, new DefinitionDecorator('security.authentication.success_handler'));
$successHandler->replaceArgument(1, array_intersect_key($config, $this->defaultSuccessHandlerOptions));
...
}
protected function createAuthenticationFailureHandler($container, $id, $config)
{
...
$failureHandler = $container->setDefinition($id, new DefinitionDecorator('security.authentication.failure_handler'));
$failureHandler->replaceArgument(2, array_intersect_key($config, $this->defaultFailureHandlerOptions));
...
}
Run Code Online (Sandbox Code Playgroud)
它专门查找security.authentication.success_handler并security.authentication.failure_handler为了从你的配置到传入的数组合并选项.我敢肯定有一种方法来为自己服务的类似设置的东西,但我还没有研究它.
希望有所帮助.
| 归档时间: |
|
| 查看次数: |
24165 次 |
| 最近记录: |