我正在使用自定义身份验证器来使用第三方服务验证登录凭据。
当我尝试在树枝内访问{{ app.user }}
时,它未定义。如果我访问{{ app.security.token.user }}
,我会将用户名作为字符串。
我需要访问当前用户的角色,但由于app.user未设置,我不知道如何执行此操作。
在分析器中,将显示用户及其角色,因此它们必须在某处可用。
任何想法为什么它们可能不可用,或者我如何才能访问这些信息?
<?php
namespace Client\AdminBundle\Security;
use Doctrine\ORM\EntityManager;
use Client\AdminBunde\Entity\User;
use Client\AdminBunde\Exception\RuntimeException;
use Client\AdminBunde\Entity\Client;
use Client\AdminBunde\Entity\ClientRepository;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
class CustomAuthenticator implements SimpleFormAuthenticatorInterface
{
/**
* @var array
*/
protected $rolesMap;
/**
* @var ClientRepository
*/
protected $clientRepository;
/**
* @var EntityManager
*/
private $entityManager;
/**
* @param array $rolesMap
* @param ClientRepository $clientRepository
* @param EntityManager $entityManager
*/
public function __construct( $rolesMap, ClientRepository $clientRepository, EntityManager $entityManager )
{
$this->rolesMap = $rolesMap;
$this->clientRepository = $clientRepository;
$this->entityManager = $entityManager;
}
/**
* @param TokenInterface $token
* @param UserProviderInterface $userProvider
* @param $providerKey
*
* @throws RuntimeException if response is not set by the time needed
*
* @return UsernamePasswordToken
*/
public function authenticateToken( TokenInterface $token, UserProviderInterface $userProvider, $providerKey )
{
$username = $token->getUsername();
$password = $token->getCredentials();
$user = new User;
$user->setUsername( $username )
->setPassword( $password );
$uri = 'http://example.com/sso-integration/auth' .
'?userId=' . urlencode( $user->getUsername() ) .
"&passwordHash=" . urlencode( $user->getPassword() );
try {
$response = $this->guzzleGet( $uri );
} catch ( RequestException $e ) {
$reason = @$e->getResponse()->getReasonPhrase();
if ( ! empty( $reason )) {
throw new AuthenticationException( 'Unable to login. ' . $reason . '.' );
}
} catch ( \Exception $e ) {
throw new AuthenticationException( 'Unable to login. Please try again.' );
}
if (empty( $response )) {
throw new RuntimeException( 'No response' );
}
if (200 != $response->getStatusCode()) {
throw new AuthenticationException(
'There was a problem connecting to the authentication service. Please try again.'
);
}
$responseJson = @$response->json();
if (empty( $responseJson['status'] )) {
throw new AuthenticationException(
'There was a problem connecting to the authentication service. Please try again.'
);
}
if ('OK' !== $responseJson['status']) {
$msg = ! empty( $responseJson['message'] ) ? $responseJson['message'] : 'Incorrect credentials';
throw new AuthenticationException( $msg );
}
if (empty( $responseJson['roles'] )) {
throw new AuthenticationException( 'Authenticated, but with no role. Please try again.' );
}
$returnedRoles = $responseJson['roles'];
if ( ! is_array( $returnedRoles )) {
$returnedRoles = [ $returnedRoles ];
}
$roles = [ ];
foreach ($returnedRoles as $role) {
if ( ! empty( $this->rolesMap[$role] )) {
$roles[] = $this->rolesMap[$role];
}
}
if (empty( $roles )) {
throw new AuthenticationException( 'Authenticated, but with no role. Please try again.' );
}
$client = @$this->clientRepository->findOneByUsername( $username );
if (empty( $client )) {
$client = new Client;
$client->setUsername( $username )
->setName( $username );
$this->entityManager->persist( $client );
$this->entityManager->flush();
}
$user->setClient( $client );
$user->setRoles( $roles );
$token = new ClientUsernamePasswordToken(
$user->getUsername(),
$user->getPassword(),
$providerKey,
$user->getRoles()
);
return $token;
}
/**
* Indicates if this class can authenticate a given token
*
* @param TokenInterface $token
* @param $providerKey
*
* @return bool
*/
public function supportsToken( TokenInterface $token, $providerKey )
{
return $token instanceof ClientUsernamePasswordToken;
}
/**
* Creates the user token with user's login credentials
*
* @param Request $request
* @param string $username
* @param string $password
* @param $providerKey
*
* @return UsernamePasswordToken
*/
public function createToken( Request $request, $username, $password, $providerKey )
{
return new ClientUsernamePasswordToken( $username, $password, $providerKey );
}
/**
* @param $uri
*
* @return ResponseInterface
*/
protected function guzzleGet( $uri )
{
$guzzleClient = new GuzzleClient();
/** @noinspection PhpVoidFunctionResultUsedInspection */
$response = $guzzleClient->get( $uri );
return $response;
}
}
<?php
/**
* Created by PhpStorm.
* User: toby
* Date: 17/07/2014
* Time: 23:51
*/
namespace Client\AdminBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class ClientUsernamePasswordToken extends UsernamePasswordToken
{
}
parameters:
client.security.authenticator.class: Client\AdminBundle\Security\ClientAuthenticator
client.form.type.client.class: Client\AdminBundle\Form\Type\ClientType
client.form.type.client_own.class: Client\AdminBundle\Form\Type\ClientOwnType
client.form.type.app.class: Client\AdminBundle\Form\Type\AppType
client.form.type.gallery.class: Client\AdminBundle\Form\Type\GalleryType
client.form.type.colour.class: Client\AdminBundle\Form\Type\ColourType
client.form.type.image.class: Client\AdminBundle\Form\Type\ImageType
client.image: Client\AdminBundle\Service\Image
client.image.sizes: []
client.image.upload_subscriber.class: Client\AdminBundle\EventListener\ImageUploadDoctrineEventListener
client.cdn.aws_s3.class: Client\AdminBundle\File\AWSS3
client.event_listener.new_image.class: Client\AdminBundle\EventListener\NewImageEventListener
client.file.path_calculator.class: Client\AdminBundle\File\PathCalculator
client.eventlistener.admin_cache_prevention.class: Client\AdminBundle\EventListener\AdminCachePreventionEventSubscriber
client.eventlistener.varnish_cache_clear.class: Client\AdminBundle\EventListener\VarnishCacheClearListener
services:
client.security.authenticator:
class: %client.security.authenticator.class%
arguments: [%client.user_roles%, @client.repository.client, @doctrine.orm.default_entity_manager]
client.form.type.client:
class: %client.form.type.client.class%
tags:
- { name: form.type, alias: client }
client.form.type.client_own:
class: %client.form.type.client_own.class%
tags:
- { name: form.type, alias: client_own }
client.form.type.app:
class: %client.form.type.app.class%
calls:
- [setImageService, [@client.image]]
tags:
- { name: form.type, alias: app }
client.form.type.gallery:
class: %client.form.type.gallery.class%
calls:
- [setAppRepository, [@client.repository.app]]
- [setImageService, [@client.image]]
tags:
- { name: form.type, alias: gallery }
client.form.type.colour:
class: %client.form.type.colour.class%
tags:
- { name: form.type, alias: colour }
client.form.type.image:
class: %client.form.type.image.class%
calls:
- [setImageService, [@client.image]]
tags:
- { name: form.type, alias: image }
client.image:
class: %client.image%
calls:
- [setRouter, [@router.default]]
- [setEventDispatcher, [@event_dispatcher]]
- [setCdn, [@client.cdn.aws_s3]]
- [setSizes, [%client.image.sizes%]]
- [setImageQuality, [%client.images.resize_quality%]]
client.image.upload_subscriber:
class: %client.image.upload_subscriber.class%
calls:
- [setImageService, [@client.image]]
- [setEventDispatcher, [@event_dispatcher]]
- [setPathCalculator, [@client.file.path_calculator]]
- [setLogger, [@monolog.logger]]
tags:
- { name: doctrine.event_listener, event: uploadablePostFileProcess }
client.cdn.aws_s3:
class: %client.cdn.aws_s3.class%
arguments: [@aws_s3, %aws_s3_images_bucket%, %aws_cloudfront_domains%]
calls:
- [setRequestStack, [@request_stack]]
client.event_listener.new_image:
class: %client.event_listener.new_image.class%
calls:
- [setCdn, [@client.cdn.aws_s3]]
- [setPathCalculator, [@client.file.path_calculator]]
tags:
- { name: kernel.event_subscriber }
client.file.path_calculator:
class: %client.file.path_calculator.class%
calls:
- [setWebRoot, [%webroot%]]
client.eventlistener.admin_cache_prevention:
class: %client.eventlistener.admin_cache_prevention.class%
tags:
- { name: kernel.event_subscriber }
client.eventlistener.varnish_cache_clear:
class: %client.eventlistener.varnish_cache_clear.class%
calls:
- [setContainer, [@service_container]]
- [setRouter, [@router.default]]
tags:
- { name: doctrine.event_subscriber }
security:
providers:
in_memory:
memory:
users:
# Users now handled by Client SSO integration
# ryan: { password: ryanpass, roles: 'ROLE_USER' }
# admin: { password: kittens, roles: 'ROLE_ADMIN' }
# disco-superuser: { password: flxpwd, roles: 'ROLE_ADMIN' }
role_hierarchy:
#...
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
simple_form:
authenticator: client.security.authenticator
login_path: login
check_path: login_check
csrf_provider: form.csrf_provider
default_target_path: login_redirect
remember_me:
key: "%secret%"
lifetime: 31536000 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
logout:
path: logout
target: login
access_control:
# ...
encoders:
Symfony\Component\Security\Core\User\User: plaintext
答案 0 :(得分:1)
如果您有权访问用户名,那么您也可以访问角色,因为{{ app.security.token }}
正在返回TokenInterface(请参阅Api参考)。然后,您可以在方法中的模板{{ app.security.token.getRoles() }}
或$token->getUsername();
中获得角色。
答案 1 :(得分:0)
您尝试访问的页面是否受防火墙保护?默认情况下,只有这样的页面才能从模板访问用户。
答案 2 :(得分:0)
{{ app.security.token.user }}
来自安全上下文。 {{ app.user }}
来自用户提供商。它们可以被映射。您是否正确设置了the user provider?我看到你配置了User
个实体,所以在你的情况下app/config/security.yml
应该有类似的东西我猜:
security:
providers:
main:
entity:
class: Client\AdminBunde\Entity\User
property: username