重定向后 Symfony 身份验证令牌丢失
Symfony Authentication Token lost after redirect
首先,不要费心去复制这段代码。这将很快在我的 github 上可用。 (我会更新这个 post 以防万一有人需要它)
你好。我正在尝试使用 Steam 在我的应用程序中进行连接。因此,我尝试创建自定义用户提供程序和自定义身份验证。单击“登录”按钮后,我的用户(我自己添加了一个)从数据库加载,我被重定向到我的自定义页面。在该页面中,我的调试工具栏告诉我我已使用自定义令牌和防火墙进行身份验证。如果我转到另一个页面,例如“/search”,我的调试工具栏会告诉我我不再通过身份验证...
我做错了什么?
我正在使用 Symfony 4.0.6。谢谢!
P.S.: 这个脚本的灵感来自这个:https://github.com/SirWaddles/SteamAuthBundle
P.P.S: 如果我遗漏了任何文件而您需要它,请回复。
P.P.P.S:我觉得是serialize()
和unserialize()
的问题,具体我也不清楚
Player.php
<?php
namespace App\Entity;
use App\Service\SteamAuth\User\SteamUserInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class Player
* @package App\Entity
*
* @ORM\Entity(repositoryClass="App\Repository\PlayerRepository")
* @ORM\Table(name="players")
*/
class Player implements UserInterface, SteamUserInterface, AdvancedUserInterface, EquatableInterface, \Serializable
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @var int
*/
private $id;
/**
* @ORM\Column(type="string", length=255, )
*
* @var string
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $name;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $password;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var null|string
*/
private $avatar;
/**
* @var array
*
* @ORM\Column(type="array")
*/
private $roles;
/**
* @var \DateTime|null
*
* @ORM\Column(type="datetime", nullable=true)
*/
private $lastSync;
/**
* @var bool
*
* @ORM\Column(type="boolean")
*/
private $enabled;
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @param int $id
*
* @return Player
*/
public function setId(int $id): Player
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getUsername(): string
{
return $this->username;
}
/**
* @param string $username
*
* @return Player
*/
public function setUsername(string $username): Player
{
$this->username = $username;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*
* @return Player
*/
public function setName(string $name): Player
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* @return array
*/
public function getRoles()
{
return $this->roles;
}
/**
* @param array $roles
* @return Player
*/
public function setRoles(array $roles): Player
{
$this->roles = $roles;
return $this;
}
/**
* @return \DateTime|null
*/
public function getLastSync(): ?\DateTime
{
return $this->lastSync;
}
/**
* @param \DateTime|null $lastSync
* @return Player
*/
public function setLastSync(?\DateTime $lastSync): Player
{
$this->lastSync = $lastSync;
return $this;
}
/**
* @return null|string
*/
public function getSalt()
{
return null;
}
/**
* @param string $password
* @return Player
*/
public function setPassword(string $password): Player
{
$this->password = $password;
return $this;
}
/**
* @return null|string
*/
public function getAvatar(): ?string
{
return $this->avatar;
}
/**
* @param null|string $avatar
*
* @return Player
*/
public function setAvatar(?string $avatar): Player
{
$this->avatar = $avatar;
return $this;
}
/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
}
/**
* {@inheritdoc}
*/
public function isAccountNonExpired()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isAccountNonLocked()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isEnabled()
{
return $this->enabled;
}
/**
* @param bool|null $enabled
* @return Player
*/
public function setEnabled(?bool $enabled): Player
{
$this->enabled = $enabled;
return $this;
}
/**
* {@inheritdoc}
*/
public function isEqualTo(UserInterface $user)
{
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function serialize()
{
return serialize([
$this->id,
$this->username,
$this->name,
$this->avatar,
$this->password,
$this->enabled
]);
}
/**
* {@inheritdoc}
*/
public function unserialize($data)
{
list($this->id, $this->username, $this->name, $this->avatar, $this->password, $this->enabled) = unserialize($data);
}
/**
* @return string
*/
public function __toString()
{
return $this->getUsername() ?? '-';
}
}
SteamToken.php
<?php
namespace App\Service\SteamAuth\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
/**
* Class SteamToken
* @package App\Service\SteamAuth\Token
*/
class SteamToken extends AbstractToken
{
/**
* {@inheritdoc}
*/
public function __construct(array $roles = [])
{
parent::__construct($roles);
$this->setAuthenticated(count($roles) > 0);
}
/**
* {@inheritdoc}
*/
public function setAttributes(array $attributes)
{
foreach ($attributes as $key => $attribute) {
$key = str_replace("openid_", "openid.", $key);
$this->setAttribute($key, $attribute);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getCredentials()
{
}
/**
* {@inheritdoc}
*/
public function serialize()
{
return serialize([
$this->getUser(),
$this->isAuthenticated(),
$this->getAttributes()
]);
}
/**
* {@inheritdoc}
*/
public function unserialize($data)
{
$data = unserialize($data);
$this->setUser($data[0]);
$this->setAuthenticated($data[1]);
$this->setAttributes($data[2]);
}
}
SteamListener.php
<?php
namespace App\Service\SteamAuth\Firewall;
use App\Service\SteamAuth\Token\SteamToken;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
/**
* Class SteamListener
* @package App\Service\SteamAuth
*/
class SteamListener implements ListenerInterface
{
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var AuthenticationManagerInterface
*/
private $authentication;
/**
* SteamListener constructor.
*
* @param TokenStorageInterface $tokenStorage
* @param AuthenticationManagerInterface $authentication
*/
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authentication)
{
$this->tokenStorage = $tokenStorage;
$this->authentication = $authentication;
}
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if($request->get('_route') === 'login_check') {
$token = new SteamToken();
$token->setUser(str_replace("http://steamcommunity.com/openid/id/", "", $request->query->get('openid_claimed_id')));
$token->setAttributes($request->query->all());
try {
$authToken = $this->authentication->authenticate($token);
$this->tokenStorage->setToken($authToken);
return;
} catch (AuthenticationException $exception) {
}
}
$response = new Response();
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$event->setResponse($response);
return;
}
}
SteamProvider.php
<?php
namespace App\Service\SteamAuth\Authentication;
use App\Service\SteamAuth\Token\SteamToken;
use GuzzleHttp\Client;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* Class SteamProvider
* @package App\Service\SteamAuth\Provider
*/
class SteamProvider implements AuthenticationProviderInterface
{
/**
* @var UserProviderInterface
*/
private $userProvider;
/**
* @var Client
*/
private $client;
/**
* SteamProvider constructor.
*
* @param UserProviderInterface $userProvider
* @param Client $client
*/
public function __construct(UserProviderInterface $userProvider, Client $client)
{
$this->userProvider = $userProvider;
$this->client = $client;
}
/**
* {@inheritdoc}
*/
public function authenticate(TokenInterface $token)
{
if ($token->getAttribute('openid.ns') !== "http://specs.openid.net/auth/2.0") {
throw new AuthenticationException("Invalid token !");
}
$checkAuth = $token->getAttributes();
$checkAuth['openid.mode'] = 'check_authentication';
$response = $this->client->request('GET', 'login', ['query' => $checkAuth]);
if ((string)$response->getBody() === "ns:http://specs.openid.net/auth/2.0\nis_valid:true\n") {
$user = $this->userProvider->loadUserByUsername($token->getUsername());
$authToken = new SteamToken($user->getRoles());
$authToken->setUser($user);
return $authToken;
}
throw new AuthenticationException("Invalid token !");
}
/**
* {@inheritdoc}
*/
public function supports(TokenInterface $token)
{
return $token instanceof SteamToken;
}
}
SteamUserProvider.php
<?php
namespace App\Service\SteamAuth\User;
use App\Entity\Player;
use App\Service\SteamAuth\SteamUserService;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* Class SteamUserProvider
* @package App\Service\SteamAuth\User
*/
class SteamUserProvider implements UserProviderInterface
{
/**
* @var EntityManager
*/
private $entityManager;
/**
* @var string
*/
private $userClass;
/**
* @var SteamUserService
*/
private $userService;
/**
* SteamUserProvider constructor.
*
* @param EntityManager $entityManager
* @param SteamUserService $userService
* @param string $userClass
*/
public function __construct(EntityManager $entityManager, SteamUserService $userService, string $userClass)
{
$this->entityManager = $entityManager;
$this->userService = $userService;
$this->userClass = $userClass;
}
/**
* {@inheritdoc}
*/
public function loadUserByUsername($username)
{
$repository = $this->entityManager->getRepository($this->userClass);
$player = $repository->findOneBy(['username' => $username]);
if (!$player) {
/**
* @var $player Player
*/
$player = new $this->userClass();
$player->setUsername($username);
$player->setPassword(md5(random_bytes(15)));
$player->setRoles(['ROLE_USER']);
$player->setEnabled(1);
$player = $this->userService->updateUserEntry($player);
$this->entityManager->persist($player);
$this->entityManager->flush($player);
}
/// if last update....
return $player;
}
/**
* {@inheritdoc}
*/
public function refreshUser(UserInterface $user)
{
if (!$user instanceof SteamUserInterface) {
throw new UnsupportedUserException("User not supported!");
}
return $this->loadUserByUsername($user->getUsername());
}
/**
* {@inheritdoc}
*/
public function supportsClass($class)
{
return $class === $this->userClass;
}
}
services.yaml
services:
...
# Aliases
GuzzleHttp\Client: '@eight_points_guzzle.client.login'
# Log In System
app.steam_user.service:
class: App\Service\SteamAuth\SteamUserService
arguments: ['@eight_points_guzzle.client.steam', '%steam_api_key%']
app.steam_user.provider:
class: App\Service\SteamAuth\User\SteamUserProvider
arguments:
$entityManager: '@doctrine.orm.default_entity_manager'
$userService: '@app.steam_user.service'
$userClass: '%steam_user_class%'
app.steam.provider:
class: App\Service\SteamAuth\Authentication\SteamProvider
arguments:
$userProvider: '@app.steam_user.provider'
$client: '@eight_points_guzzle.client.login'
app.steam.listener:
class: App\Service\SteamAuth\Firewall\SteamListener
security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
steamauth:
id: app.steam_user.provider
firewalls:
steam_auth:
pattern: ^/login_check
stateless: true
steam: ~
form_login:
csrf_token_generator: security.csrf.token_manager
remember_me:
secret: '%kernel.secret%'
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
编辑:如果我 dump($this->get('session')->all())
和刷新前的那个页面,我得到这个:"_security_steam_auth" => "C:38:"App\Service\SteamAuth\Token\SteamToken":40:{a:4:{i:0;N;i:1;b:0;i:2;a:0:{}i:3;a:0:{}}}"
我遇到了类似的问题。
我的序列化过程中缺少一个属性:isActive
我一直不明白为什么,但是当这个属性是我的 serialization/unserialization 进程时,它工作正常,如果不是,它根本不起作用。
这是我的来源:https://github.com/matthieuleorat/documentManager/blob/master/src/Entity/User.php#L253
文档:http://symfony.com/doc/current/security/entity_provider.html#security-serialize-equatable
希望对您有所帮助。
你有module_suhosin7启用吗?
我们在启用 suhosin7 的会话中遇到问题。
事实上,它添加了一些关于会话和 cookie 管理的规则。
如果启用,请尝试禁用它并检查它是否有效。
suhosin7 的会话加密存在一个已知问题:
https://github.com/sektioneins/suhosin7/issues/21
SteamListener.php 中的这一行阻止任何其他路由工作。
$request = $event->getRequest();
if($request->get('_route') === 'login_check') {
[...]
}
$response = new Response();
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$event->setResponse($response);
每次导航到页面时都会调用安全防火墙 handle() 函数,因此如果您将其他页面状态设置为禁止,您将无法在登录以外的其他页面上导航。
这应该通过删除它来工作。如果问题解决了请告诉我
经过大量工作,我决定再次研究 Steam 身份验证包,我找到了一个用于 Symfony 4 的包,我确认它可以工作。
Link: https://github.com/knojector/SteamAuthenticationBundle
首先,不要费心去复制这段代码。这将很快在我的 github 上可用。 (我会更新这个 post 以防万一有人需要它)
你好。我正在尝试使用 Steam 在我的应用程序中进行连接。因此,我尝试创建自定义用户提供程序和自定义身份验证。单击“登录”按钮后,我的用户(我自己添加了一个)从数据库加载,我被重定向到我的自定义页面。在该页面中,我的调试工具栏告诉我我已使用自定义令牌和防火墙进行身份验证。如果我转到另一个页面,例如“/search”,我的调试工具栏会告诉我我不再通过身份验证...
我做错了什么?
我正在使用 Symfony 4.0.6。谢谢!
P.S.: 这个脚本的灵感来自这个:https://github.com/SirWaddles/SteamAuthBundle
P.P.S: 如果我遗漏了任何文件而您需要它,请回复。
P.P.P.S:我觉得是serialize()
和unserialize()
的问题,具体我也不清楚
Player.php
<?php
namespace App\Entity;
use App\Service\SteamAuth\User\SteamUserInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class Player
* @package App\Entity
*
* @ORM\Entity(repositoryClass="App\Repository\PlayerRepository")
* @ORM\Table(name="players")
*/
class Player implements UserInterface, SteamUserInterface, AdvancedUserInterface, EquatableInterface, \Serializable
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @var int
*/
private $id;
/**
* @ORM\Column(type="string", length=255, )
*
* @var string
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $name;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $password;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var null|string
*/
private $avatar;
/**
* @var array
*
* @ORM\Column(type="array")
*/
private $roles;
/**
* @var \DateTime|null
*
* @ORM\Column(type="datetime", nullable=true)
*/
private $lastSync;
/**
* @var bool
*
* @ORM\Column(type="boolean")
*/
private $enabled;
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @param int $id
*
* @return Player
*/
public function setId(int $id): Player
{
$this->id = $id;
return $this;
}
/**
* @return string
*/
public function getUsername(): string
{
return $this->username;
}
/**
* @param string $username
*
* @return Player
*/
public function setUsername(string $username): Player
{
$this->username = $username;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*
* @return Player
*/
public function setName(string $name): Player
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* @return array
*/
public function getRoles()
{
return $this->roles;
}
/**
* @param array $roles
* @return Player
*/
public function setRoles(array $roles): Player
{
$this->roles = $roles;
return $this;
}
/**
* @return \DateTime|null
*/
public function getLastSync(): ?\DateTime
{
return $this->lastSync;
}
/**
* @param \DateTime|null $lastSync
* @return Player
*/
public function setLastSync(?\DateTime $lastSync): Player
{
$this->lastSync = $lastSync;
return $this;
}
/**
* @return null|string
*/
public function getSalt()
{
return null;
}
/**
* @param string $password
* @return Player
*/
public function setPassword(string $password): Player
{
$this->password = $password;
return $this;
}
/**
* @return null|string
*/
public function getAvatar(): ?string
{
return $this->avatar;
}
/**
* @param null|string $avatar
*
* @return Player
*/
public function setAvatar(?string $avatar): Player
{
$this->avatar = $avatar;
return $this;
}
/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
}
/**
* {@inheritdoc}
*/
public function isAccountNonExpired()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isAccountNonLocked()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* {@inheritdoc}
*/
public function isEnabled()
{
return $this->enabled;
}
/**
* @param bool|null $enabled
* @return Player
*/
public function setEnabled(?bool $enabled): Player
{
$this->enabled = $enabled;
return $this;
}
/**
* {@inheritdoc}
*/
public function isEqualTo(UserInterface $user)
{
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function serialize()
{
return serialize([
$this->id,
$this->username,
$this->name,
$this->avatar,
$this->password,
$this->enabled
]);
}
/**
* {@inheritdoc}
*/
public function unserialize($data)
{
list($this->id, $this->username, $this->name, $this->avatar, $this->password, $this->enabled) = unserialize($data);
}
/**
* @return string
*/
public function __toString()
{
return $this->getUsername() ?? '-';
}
}
SteamToken.php
<?php
namespace App\Service\SteamAuth\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
/**
* Class SteamToken
* @package App\Service\SteamAuth\Token
*/
class SteamToken extends AbstractToken
{
/**
* {@inheritdoc}
*/
public function __construct(array $roles = [])
{
parent::__construct($roles);
$this->setAuthenticated(count($roles) > 0);
}
/**
* {@inheritdoc}
*/
public function setAttributes(array $attributes)
{
foreach ($attributes as $key => $attribute) {
$key = str_replace("openid_", "openid.", $key);
$this->setAttribute($key, $attribute);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getCredentials()
{
}
/**
* {@inheritdoc}
*/
public function serialize()
{
return serialize([
$this->getUser(),
$this->isAuthenticated(),
$this->getAttributes()
]);
}
/**
* {@inheritdoc}
*/
public function unserialize($data)
{
$data = unserialize($data);
$this->setUser($data[0]);
$this->setAuthenticated($data[1]);
$this->setAttributes($data[2]);
}
}
SteamListener.php
<?php
namespace App\Service\SteamAuth\Firewall;
use App\Service\SteamAuth\Token\SteamToken;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
/**
* Class SteamListener
* @package App\Service\SteamAuth
*/
class SteamListener implements ListenerInterface
{
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var AuthenticationManagerInterface
*/
private $authentication;
/**
* SteamListener constructor.
*
* @param TokenStorageInterface $tokenStorage
* @param AuthenticationManagerInterface $authentication
*/
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authentication)
{
$this->tokenStorage = $tokenStorage;
$this->authentication = $authentication;
}
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if($request->get('_route') === 'login_check') {
$token = new SteamToken();
$token->setUser(str_replace("http://steamcommunity.com/openid/id/", "", $request->query->get('openid_claimed_id')));
$token->setAttributes($request->query->all());
try {
$authToken = $this->authentication->authenticate($token);
$this->tokenStorage->setToken($authToken);
return;
} catch (AuthenticationException $exception) {
}
}
$response = new Response();
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$event->setResponse($response);
return;
}
}
SteamProvider.php
<?php
namespace App\Service\SteamAuth\Authentication;
use App\Service\SteamAuth\Token\SteamToken;
use GuzzleHttp\Client;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* Class SteamProvider
* @package App\Service\SteamAuth\Provider
*/
class SteamProvider implements AuthenticationProviderInterface
{
/**
* @var UserProviderInterface
*/
private $userProvider;
/**
* @var Client
*/
private $client;
/**
* SteamProvider constructor.
*
* @param UserProviderInterface $userProvider
* @param Client $client
*/
public function __construct(UserProviderInterface $userProvider, Client $client)
{
$this->userProvider = $userProvider;
$this->client = $client;
}
/**
* {@inheritdoc}
*/
public function authenticate(TokenInterface $token)
{
if ($token->getAttribute('openid.ns') !== "http://specs.openid.net/auth/2.0") {
throw new AuthenticationException("Invalid token !");
}
$checkAuth = $token->getAttributes();
$checkAuth['openid.mode'] = 'check_authentication';
$response = $this->client->request('GET', 'login', ['query' => $checkAuth]);
if ((string)$response->getBody() === "ns:http://specs.openid.net/auth/2.0\nis_valid:true\n") {
$user = $this->userProvider->loadUserByUsername($token->getUsername());
$authToken = new SteamToken($user->getRoles());
$authToken->setUser($user);
return $authToken;
}
throw new AuthenticationException("Invalid token !");
}
/**
* {@inheritdoc}
*/
public function supports(TokenInterface $token)
{
return $token instanceof SteamToken;
}
}
SteamUserProvider.php
<?php
namespace App\Service\SteamAuth\User;
use App\Entity\Player;
use App\Service\SteamAuth\SteamUserService;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* Class SteamUserProvider
* @package App\Service\SteamAuth\User
*/
class SteamUserProvider implements UserProviderInterface
{
/**
* @var EntityManager
*/
private $entityManager;
/**
* @var string
*/
private $userClass;
/**
* @var SteamUserService
*/
private $userService;
/**
* SteamUserProvider constructor.
*
* @param EntityManager $entityManager
* @param SteamUserService $userService
* @param string $userClass
*/
public function __construct(EntityManager $entityManager, SteamUserService $userService, string $userClass)
{
$this->entityManager = $entityManager;
$this->userService = $userService;
$this->userClass = $userClass;
}
/**
* {@inheritdoc}
*/
public function loadUserByUsername($username)
{
$repository = $this->entityManager->getRepository($this->userClass);
$player = $repository->findOneBy(['username' => $username]);
if (!$player) {
/**
* @var $player Player
*/
$player = new $this->userClass();
$player->setUsername($username);
$player->setPassword(md5(random_bytes(15)));
$player->setRoles(['ROLE_USER']);
$player->setEnabled(1);
$player = $this->userService->updateUserEntry($player);
$this->entityManager->persist($player);
$this->entityManager->flush($player);
}
/// if last update....
return $player;
}
/**
* {@inheritdoc}
*/
public function refreshUser(UserInterface $user)
{
if (!$user instanceof SteamUserInterface) {
throw new UnsupportedUserException("User not supported!");
}
return $this->loadUserByUsername($user->getUsername());
}
/**
* {@inheritdoc}
*/
public function supportsClass($class)
{
return $class === $this->userClass;
}
}
services.yaml
services:
...
# Aliases
GuzzleHttp\Client: '@eight_points_guzzle.client.login'
# Log In System
app.steam_user.service:
class: App\Service\SteamAuth\SteamUserService
arguments: ['@eight_points_guzzle.client.steam', '%steam_api_key%']
app.steam_user.provider:
class: App\Service\SteamAuth\User\SteamUserProvider
arguments:
$entityManager: '@doctrine.orm.default_entity_manager'
$userService: '@app.steam_user.service'
$userClass: '%steam_user_class%'
app.steam.provider:
class: App\Service\SteamAuth\Authentication\SteamProvider
arguments:
$userProvider: '@app.steam_user.provider'
$client: '@eight_points_guzzle.client.login'
app.steam.listener:
class: App\Service\SteamAuth\Firewall\SteamListener
security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
steamauth:
id: app.steam_user.provider
firewalls:
steam_auth:
pattern: ^/login_check
stateless: true
steam: ~
form_login:
csrf_token_generator: security.csrf.token_manager
remember_me:
secret: '%kernel.secret%'
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
编辑:如果我 dump($this->get('session')->all())
和刷新前的那个页面,我得到这个:"_security_steam_auth" => "C:38:"App\Service\SteamAuth\Token\SteamToken":40:{a:4:{i:0;N;i:1;b:0;i:2;a:0:{}i:3;a:0:{}}}"
我遇到了类似的问题。
我的序列化过程中缺少一个属性:isActive 我一直不明白为什么,但是当这个属性是我的 serialization/unserialization 进程时,它工作正常,如果不是,它根本不起作用。
这是我的来源:https://github.com/matthieuleorat/documentManager/blob/master/src/Entity/User.php#L253
文档:http://symfony.com/doc/current/security/entity_provider.html#security-serialize-equatable
希望对您有所帮助。
你有module_suhosin7启用吗?
我们在启用 suhosin7 的会话中遇到问题。 事实上,它添加了一些关于会话和 cookie 管理的规则。
如果启用,请尝试禁用它并检查它是否有效。
suhosin7 的会话加密存在一个已知问题: https://github.com/sektioneins/suhosin7/issues/21
SteamListener.php 中的这一行阻止任何其他路由工作。
$request = $event->getRequest();
if($request->get('_route') === 'login_check') {
[...]
}
$response = new Response();
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$event->setResponse($response);
每次导航到页面时都会调用安全防火墙 handle() 函数,因此如果您将其他页面状态设置为禁止,您将无法在登录以外的其他页面上导航。
这应该通过删除它来工作。如果问题解决了请告诉我
经过大量工作,我决定再次研究 Steam 身份验证包,我找到了一个用于 Symfony 4 的包,我确认它可以工作。
Link: https://github.com/knojector/SteamAuthenticationBundle