我正在使用symfony 3.3微框架。我没有使用FOSUserbundle,因为我没有用户名和电子邮件(由于社交登录不是必需的)。我使用symfonys保护认证系统使用自定义身份验证。一切正常,但是当我要实现REMEMBER me功能时。它不起作用。以下是我用过的各种文件。
security.yml
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
encoders:
AdminBundle\Entity\User:
algorithm: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_ADMIN
ROLE_USER: ROLE_USER
providers:
in_memory:
memory: ~
token_user_provider:
entity:
class: AdminBundle:User
property: authToken
login_form_provider:
entity:
class: AdminBundle:User
property: email
firewalls:
main:
pattern: ^/api/
provider: token_user_provider
logout: true
anonymous: true
guard:
authenticators:
- api_key_authenticator
admin:
anonymous: ~
provider: login_form_provider
logout:
path: admin_logout
target: admin_login
guard:
authenticators:
- form_authenticator
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week
path: ^/admin/
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/reset-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, roles: [IS_AUTHENTICATED_FULLY,IS_AUTHENTICATED_REMEMBERED] }
- { path: ^/api/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/user/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/user/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/page/about-us, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/page/terms-and-condition, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/page/faq, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/page/privacy-policy, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/consent/submit, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: ROLE_USER }
LoginFormAuthenticator.php
<?php
namespace AdminBundle\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
class LoginFormAuthenticator extends AbstractGuardAuthenticator {
/**
* @var \Symfony\Component\Routing\RouterInterface
*/
private $router;
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
private $container;
/**
* Default message for authentication failure.
*
* @var string
*/
private $failMessage = 'Invalid credentials';
/**
* Creates a new instance of FormAuthenticator
*/
public function __construct(RouterInterface $router, ContainerInterface $container) {
$this->router = $router;
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function getCredentials(Request $request) {
if ($request->get('_route') != 'admin_login' || !$request->isMethod('POST')) {
return null;
}
// Check invalid CSRF token
$csrfToken = $request->request->get('_csrf_token');
$csrftokenManager = $this->container->get('security.csrf.token_manager');
if (false === $csrftokenManager->isTokenValid(new CsrfToken('authenticate', $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
}
return array(
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
);
}
/**
* {@inheritdoc}
*/
public function getUser($credentials, UserProviderInterface $userProvider) {
try {
return $userProvider->loadUserByUsername($credentials['email']);
} catch (UsernameNotFoundException $e) {
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
}
/**
* {@inheritdoc}
*/
public function checkCredentials($credentials, UserInterface $user) {
if(!in_array('ROLE_ADMIN', $user->getRoles()))
{
throw new CustomUserMessageAuthenticationException("You don't have right to access this page.");
}
$factory = $this->container->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$salt = $user->getSalt();
if($encoder->isPasswordValid($user->getPassword(), $credentials['password'], $salt)) {
return true;
}
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
/**
* {@inheritdoc}
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) {
$url = $this->router->generate('admin_dashboard');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
$url = $this->router->generate('admin_login');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function start(Request $request, AuthenticationException $authException = null) {
$url = $this->router->generate('admin_login');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function supportsRememberMe() {
return true;
}
}
dev.log
[2017-11-10 14:44:24] request.INFO: Matched route "admin_dashboard". {"route":"admin_dashboard","route_parameters":{"_controller":"AdminBundle\\Controller\\DashboardController::indexAction","_route":"admin_dashboard"},"request_uri":"http://localhost/bitcoin-consentsy/public/index.php/admin/dashboard","method":"GET"} []
[2017-11-10 14:44:24] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"admin","authenticators":1} []
[2017-11-10 14:44:24] security.DEBUG: Calling getCredentials() on guard configurator. {"firewall_key":"admin","authenticator":"AdminBundle\\Security\\LoginFormAuthenticator"} []
[2017-11-10 14:44:24] security.DEBUG: Remember-me cookie detected. [] []
[2017-11-10 14:44:25] doctrine.DEBUG: SELECT t0.id AS id_1, t0.email AS email_2, t0.password AS password_3, t0.is_active AS is_active_4, t0.device_id AS device_id_5, t0.device_type AS device_type_6, t0.provide AS provide_7, t0.identifier AS identifier_8, t0.roles AS roles_9, t0.auth_token AS auth_token_10, t0.reset_token AS reset_token_11, t0.is_registration_mail_sent AS is_registration_mail_sent_12, t0.firstname AS firstname_13, t0.lastname AS lastname_14, t0.created_at AS created_at_15, t0.updated_at AS updated_at_16 FROM users t0 WHERE t0.email = ? LIMIT 1 [""] []
[2017-11-10 14:44:25] security.INFO: User for remember-me cookie not found. [] []
[2017-11-10 14:44:25] security.DEBUG: Clearing remember-me cookie. {"name":"REMEMBERME"} []
[2017-11-10 14:44:25] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-11-10 14:44:25] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at E:\\xampp\\htdocs\\bitcoin-consentsy\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\Security\\Http\\Firewall\\AccessListener.php:70)"} []
请帮我解决这个问题。感谢您的帮助。
答案 0 :(得分:0)
好的,我找到了。
“警告:如果用户使用”记住我“功能登录,则单独检查'IS_AUTHENTICATED_FULLY'将返回false。”
所以,只需用 IS_AUTHENTICATED_REMEMBERED
替换 IS_AUTHENTICATED_FULLYHow to check if an user is logged in Symfony2 inside a controller?
享受