Symfony2 login_check и собственный поставщик аутентификацииPhp

Кемеровские программисты php общаются здесь
Anonymous
Symfony2 login_check и собственный поставщик аутентификации

Сообщение Anonymous »

У меня есть следующие файлы кода из моего проекта, которые отлично работают с пользовательским поставщиком аутентификации, и я могу перехватить запрос в аутентификации (TokenInterface $token), я поставил echo «это сработало»; Выход; чтобы напечатать сообщение на экране, чтобы сообщить мне, что оно введено в метод аутентификации() в файле AuthProvider.php.

Но проблема возникает, когда я пытаюсь изменить < Strong>login_path:/login к login_path:/user/login и от check_path:/login_check к check_path:/user/login_check а также измените файл маршрутизации.yml, чтобы позволить UserBundle иметь префикс /user, тогда код будет работать, но он не войдет в authenticate(), а напечатает "Представленный пароль недействителен" вместо "Неверные учетные данные", как я могу изменить параметры login_check и check_path на другие значения, кроме входа и входа в систему соответственно, и позволить моему пользовательскому поставщику аутентификации работать с новыми настройками?

// app/config/security.yml

security:
factories:
- "%kernel.root_dir%/../src/FD/UserBundle/Resources/config/security_factories.yml"

firewalls:
checkpoint:
pattern: ^/
user: true
form_login:
login_path: /login
check_path: /login_check
logout:
path: /logout
target: /
anonymous: ~

encoders:
FD\UserBundle\Entity\User: sha512

role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

providers:
user_provider:
id: user_provider_service

access_control:
- { path: ^/_internal, role: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
- { path: ^/user/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/event/new, roles: ROLE_ADMIN }
- { path: ^/hello, roles: ROLE_USER }


// app/config/config.yml

imports:
- { resource: parameters.ini }
- { resource: security.yml }
- { resource: @UserBundle/Resources/config/services.yml }

framework:
#esi: ~
translator: { fallback: %locale% }
secret: %secret%
charset: UTF-8
router: { resource: "%kernel.root_dir%/config/routing.yml" }
form: true
csrf_protection: false
validation: { enabled: true }
#validation: { enable_annotations: true }
templating: { engines: ['twig'] } #assets_version: SomeVersionScheme
session:
default_locale: %locale%
auto_start: true

# Twig Configuration
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%

# Assetic Configuration
assetic:
debug: %kernel.debug%
use_controller: false
# java: /usr/bin/java
filters:
cssrewrite: ~
# closure:
# jar: %kernel.root_dir%/java/compiler.jar
# yui_css:
# jar: %kernel.root_dir%/java/yuicompressor-2.4.2.jar

# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
mapping_types:
enum: string
set: string
blob: object
orm:
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default # The first defined is used if not set
entity_managers:
default:
# The name of a DBAL connection (the one marked as default is used if not set)
connection: ~
mappings: # Required
FDHelloBundle: ~
UserBundle: { type: annotation }

# mappings:
# FDHelloBundle: { type: yml, dir: Resources/config/doctrine/metadata/orm }

# Swiftmailer Configuration
swiftmailer:
transport: %mailer_transport%
host: %mailer_host%
username: %mailer_user%
password: %mailer_password%

jms_security_extra:
secure_controllers: true
secure_all_services: false

services:
fd_hello.twig.extension.debug:
class: Twig_Extension_Debug
tags:
- { name: 'twig.extension' }

user_provider_service:
class: FD\UserBundle\Security\User\UserProvider


// app/config/routing.yml

FDHelloBundle:
resource: "@FDHelloBundle/Resources/config/routing.yml"
prefix: /

FDUserBundle:
resource: "@UserBundle/Controller"
prefix: /user
type: annotation


// src/FD/UserBundle/Controller/LoginController.php

namespace FD\UserBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Security\Core\SecurityContext;

class LoginController extends Controller
{
/**
* @Route("login", name="login")
*/
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();

// get the login error if there is one
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);

return $this->render('UserBundle:Login:login.html.twig', array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}

/**
* @Route("login_check", name="login_check")
*/
public function loginCheckAction()
{

}

/**
* @Route("logout", name="logout")
*/
public function logoutAction()
{

}
}


// src/FD/UserBundle/DependencyInjection/Security/Factory/UserFactory.php

namespace FD\UserBundle\DependencyInjection\Security\Factory;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;

class UserFactory implements SecurityFactoryInterface
{
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{
$providerId = 'security.authentication.provider.user.'.$id;
$container
->setDefinition($providerId, new DefinitionDecorator('user.security.authentication.provider'))
->replaceArgument(0, new Reference($userProvider))
;
$listenerId = 'security.authentication.listener.user.'.$id;
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('user.security.authentication.listener'));

return array($providerId, $listenerId, $defaultEntryPoint);
}

public function getPosition()
{
return 'pre_auth';
}

public function getKey()
{
return 'user';
}

public function addConfiguration(NodeDefinition $node)
{}
}


// FD/UserBundle/Resources/config/services.yml

services:
user.security.authentication.provider:
class: FD\UserBundle\Security\Authentication\Provider\AuthProvider
arguments: ['', %kernel.cache_dir%/security/nonces]

user.security.authentication.listener:
class: FD\UserBundle\Security\Firewall\AuthListener


// FD/UserBundle/Resources/config/security_factories.yml

services:
security.authentication.factory.user:
class: FD\UserBundle\DependencyInjection\Security\Factory\UserFactory
tags:
- { name: security.listener.factory }


// FD/UserBundle/Security/Authentication/Provider/AuthProvider.php

namespace FD\UserBundle\Security\Authentication\Provider;

use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;

use FD\UserBundle\Security\Authentication\Token\UserToken;

class AuthProvider implements AuthenticationProviderInterface
{
private $userProvider;
private $cacheDir;

public function __construct(UserProviderInterface $userProvider, $cacheDir)
{
$this->userProvider = $userProvider;
$this->cacheDir = $cacheDir;
}

public function authenticate(TokenInterface $token)
{
// $user = $this->userProvider->loadUserByUsername($token->getUsername());
// $userToken = new UserToken();
// $userToken->setUser($user);
echo "it worked"; exit;
$newToken = new UserToken($token->getUser(), $token->getCredentials(), "user", array("ROLE_ADMIN"));
$username = $newToken->getUser();
if (empty($username)) {
throw new BadCredentialsException('Bad credentials :)');
}
return $newToken;

// if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) {
// $authenticatedToken = new UserToken($user->getRoles());
// $authenticatedToken->setUser($user);
//
// return $authenticatedToken;
// }
}

public function supports(TokenInterface $token)
{
return $token instanceof UserToken;
}
}


// FD/UserBundle/Security/Authenticaion/Token/UserToken.php

namespace FD\UserBundle\Security\Authentication\Token;

use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;

/**
* UsernamePasswordToken implements a username and password token.
*
*/

class UserToken extends AbstractToken
{
private $credentials;
private $providerKey;

/**
* Constructor.
*
* @param string $user The username (like a nickname, email address, etc.)
* @param string $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param array $roles An array of roles
*
* @throws \InvalidArgumentException
*/
public function __construct($user, $credentials, $providerKey, array $roles = array())
{
parent::__construct($roles);

if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}

$this->setUser($user);
$this->credentials = $credentials;
$this->providerKey = $providerKey;

parent::setAuthenticated(count($roles) > 0);
}

/**
* {@inheritdoc}
*/
public function setAuthenticated($isAuthenticated)
{
if ($isAuthenticated) {
throw new \LogicException('Cannot set this token to trusted after instantiation.');
}

parent::setAuthenticated(false);
}

public function getCredentials()
{
return $this->credentials;
}

public function getProviderKey()
{
return $this->providerKey;
}

/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
parent::eraseCredentials();

$this->credentials = null;
}

public function serialize()
{
return serialize(array($this->credentials, $this->providerKey, parent::serialize()));
}

public function unserialize($str)
{
list($this->credentials, $this->providerKey, $parentStr) = unserialize($str);
parent::unserialize($parentStr);
}
}


// FD/UserBundle/Security/Firewall/AuthListener.php

namespace FD\UserBundle\Security\Firewall;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;

use FD\UserBundle\Security\Authentication\Token\UserToken;

class AuthListener extends AbstractAuthenticationListener
{
protected $securityContext;
protected $authenticationManager;
protected $httpUtils;

public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager,
SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $options = array())
{
parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, "user", array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'intention' => 'authenticate',
'post_only' => true,
), $options));
}

/**
* Performs authentication.
*
* @param Request $request A Request instance
*
* @return TokenInterface The authenticated token, or null if full authentication is not possible
*
* @throws AuthenticationException if the authentication fails
*/
protected function attemptAuthentication(Request $request)
{

$username = trim($request->get($this->options['username_parameter'], null, true));
$password = $request->get($this->options['password_parameter'], null, true);

//$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);

return $this->authenticationManager->authenticate(new UserToken($username, $password, $this->providerKey));

}

public function getHttpUtils()
{
return $this->httpUtils;
}

public function setHttpUtils($httpUtils)
{
$this->httpUtils = $httpUtils;
}
}


// src/FD/UserBundle/Security/User/UserProvider.php

namespace FD\UserBundle\Security\User;

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;

use FD\UserBundle\Entity\User;

class UserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// make a call to your webservice here
// $userData = ...
// pretend it returns an array on success, false if there is no user
$user = new User();
$user->setUsername($username);
$user->setPassword("1234");
$user->setRoles(array("ROLE_ADMIN"));

return $user;

// if ($userData) {
// // $password = '...';
// // ...
//
// return new WebserviceUser($username, $password, $salt, $roles)
// } else {
// throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
// }
}

public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}

return $this->loadUserByUsername($user->getUsername());
}

public function supportsClass($class)
{
return $class === 'FD\UserBundle\Entity\User';
}
}


Подробнее здесь: https://stackoverflow.com/questions/119 ... n-provider

Вернуться в «Php»