我正在創建自定義身份驗證提供程序。我寫了我自己的身份驗證提供程序,偵聽程序,令牌和所有內容。它基於表單登錄,並且我已經遍歷代碼,並且所有內容似乎都已正確配置。一切都按正確的順序調用,並且我的身份驗證提供程序被完美調用。身份驗證提供程序成功驗證用戶身份,並返回經過身份驗證的令牌。我擴展了AbstractAuthenticationListener其中,在句柄方法中,將設置安全上下文。Symfony自定義身份驗證提供程序 - 用戶未完全登錄(登錄,未驗證)
用戶似乎已經登錄,但在調試工具欄中,令牌未設置,我看到「您未通過身份驗證」和「無令牌」。
是否有我缺少的配置設置?爲什麼用戶會登錄,身份驗證提供程序成功返回,具有已驗證的令牌,在安全上下文中設置但仍未驗證?有關如何調試的任何提示?
(如果需要,我將發佈的代碼。)
編輯:令牌定義:
這是很簡單的,從AbstractToken只是延長:
class UserToken extends AbstractToken
{
private $username;
private $password;
private $domain;
private $providerKey;
public function __construct($username, $password, $domain, $provider_key, array $roles = array('ROLE_USER'))
{
parent::__construct($roles);
$this->username = $username;
$this->password = $password;
$this->domain = $domain;
$this->providerKey = $provider_key;
}
public function getCredentials()
{
return '';
}
function getUsername() {
return $this->username;
}
function getDomain() {
return $this->domain;
}
function getPassword() {
return $this->password;
}
function getProviderKey(){
return $this->providerKey;
}
}
驗證監聽器:
class Listener extends AbstractAuthenticationListener
{
protected $authenticationManager;
public function __construct(
SecurityContextInterface $securityContext,
AuthenticationManagerInterface $authenticationManager,
SessionAuthenticationStrategyInterface $sessionStrategy,
HttpUtils $httpUtils,
$providerKey,
AuthenticationSuccessHandlerInterface $successHandler,
AuthenticationFailureHandlerInterface $failureHandler,
array $options = array(),
LoggerInterface $logger = null,
EventDispatcherInterface $dispatcher = null
//CsrfProviderInterface $csrfProvider = null
) {
parent::__construct(
$securityContext,
$authenticationManager,
$sessionStrategy,
$httpUtils,
$providerKey,
$successHandler,
$failureHandler,
array_merge(
array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'domain_parameter' => '_domain',
'csrf_parameter' => '_csrf_token',
'intention' => 'authenticate',
'post_only' => true,
),
$options
),
$logger,
$dispatcher
);
}
/**
* Performs authentication.
*
* @param Request $request A Request instance
*
* @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response
*
* @throws AuthenticationException if the authentication fails
*/
protected function attemptAuthentication(Request $request)
{
// Create initial unauthenticated token and pass data to the authentication manager.
// TODO validate request data.
$username = trim($request->request->get($this->options['username_parameter'], null, true));
$password = $request->request->get($this->options['password_parameter'], null, true);
$domain = $request->request->get($this->options['domain_parameter'], null, true);
$token = $this->authenticationManager->authenticate(new UserToken($username, $password, $domain, $this->providerKey));
return $token;
}
}
上述代碼將調用提供的auth函數通過的AuthenticationManager R:
//This is from the AuthenticationProvider
public function authenticate(TokenInterface $token) {
$loginHandler = new LoginAuthenticationHandler($token->getUsername(), $token->getPassword(), $token->getDomain());
//This code just calls our web service and authenticates. I removed some business logic here, but this shows the gist of it.
if(!$boAuthenticationToken = $loginHandler->authenticate())
{
throw new AuthenticationException('Bad credentials');
}
else{
$user = $this->userProvider->loadUserByUsername($token->getUsername());
//$user = $this->userProvider->getUser($token, $boAuthenticationToken);
// Set the user which will be invoked in the controllers.
$token->setUser($user);
$token->setAuthenticated(true);
return $token;
}
}
捆綁Services.yml
parameters:
services:
ws.security.authentication.provider:
#http://blog.vandenbrand.org/2012/06/19/symfony2-authentication-provider-authenticate-against-webservice/
class: Aurora\OurCustomBundle\Security\Authentication\Provider\Provider
arguments: ["bo_remove_this_with_bo_auth_service", "", "@security.user_checker", "", "@security.encoder_factory"]
ws.security.authentication.listener:
class: Aurora\OurCustomBundle\Security\Firewall\Listener
parent: security.authentication.listener.abstract
abstract: true
#arguments: []
arguments: ["@security.context", "@security.authentication.manager", "@security.authentication.session_strategy", "@security.http_utils", "ws.user_provider", "@security.authentication.customized_success_handler", "@main.cas.rest.user.authentication.failure.service"]
ws.user_provider:
class: Aurora\OurCustomBundle\Security\User\UserProvider
最後,在UserProvider
class UserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
//Just return a simple user for now.
return new User($username, array('ROLE_USER'));
}
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 === 'Aurora\OurCustomBundle\Security\User\User';
}
}
只是想法。檢查您的登錄用戶是否有任何角色。你可以在profiler中做到這一點。 – kba
這味道像一個令牌問題。你可以發佈你的令牌服務定義嗎? – pcm
@kba:我查看了剖析器,似乎用戶沒有登錄。在配置文件的安全部分,它只是說「沒有令牌」。 – Foo