Symfony 4.4 Auth0 如何从应用程序中完全注销用户
Symfony 4.4 Auth0 how to completely logout user from the application
基本信息:
我创建了一个测试应用程序来测试 SSO(单点登录)是否有效。我使用 Auth0 作为 SSO 提供商。 Symfony 4.4 作为应用程序框架。我使用了来自 Auth0 的 this 文章来创建基础知识。到目前为止我可以 login/logout.
问题:
当我登录一次(使用凭据),然后注销然后再次登录时,我立即使用之前使用的相同帐户登录。无需再次填写凭据。它似乎记得会话或以某种方式没有完全注销用户。我希望用户在注销后必须使用凭据再次登录。由于我的一些用户将使用一台计算机来执行应用程序(因此需要切换用户)。
可能 fix/Extra 信息:
根据那里 docs/community 我应该看看 this。但这似乎意味着我需要 API 调用来添加 ?federated
。安装示例不使用哪个(可能是图书馆为我做的)。此外,我在由 make:auth
(或 make:user
)生成的 SecurityController 中的注销函数不再执行代码。即使我更改了函数名称,它仍然会注销我。直到我 remove/change 它停止的路线名称。这可能非常糟糕,但也许如果我有机会在注销时执行 API 调用,我可以执行此 API 调用。
我能想到的最好的事情就是更改 symfony 中的一些设置或添加一些小代码以使其正确注销。但是我不知道怎么办。
我的代码:
SecurityController.php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
// Does not trigger at all. It does not stop the page but just continues to redirect and logout.
dump($this->get('session'));
dump($session);
dump("test");
exit();
throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
}
}
Auth0ResourceOwner.php
<?php
namespace App;
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericOAuth2ResourceOwner;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
class Auth0ResourceOwner extends GenericOAuth2ResourceOwner
{
protected $paths = array(
'identifier' => 'user_id',
'nickname' => 'nickname',
'realname' => 'name',
'email' => 'email',
'profilepicture' => 'picture',
);
public function getAuthorizationUrl($redirectUri, array $extraParameters = array())
{
return parent::getAuthorizationUrl($redirectUri, array_merge(array(
'audience' => $this->options['audience'],
), $extraParameters));
}
protected function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults(array(
'authorization_url' => '{base_url}/authorize',
'access_token_url' => '{base_url}/oauth/token',
'infos_url' => '{base_url}/userinfo',
'audience' => '{base_url}/userinfo',
));
$resolver->setRequired(array(
'base_url',
));
$normalizer = function (Options $options, $value) {
return str_replace('{base_url}', $options['base_url'], $value);
};
$resolver->setNormalizer('authorization_url', $normalizer);
$resolver->setNormalizer('access_token_url', $normalizer);
$resolver->setNormalizer('infos_url', $normalizer);
$resolver->setNormalizer('audience', $normalizer);
}
}
routes.yaml
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /connect
hwi_oauth_connect:
resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect
hwi_oauth_login:
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /login
auth0_login:
path: /auth0/callback
auth0_logout:
path: /auth0/logout
# controller: App/Controller/SecurityController::logout
hwi_oauth.yaml
hwi_oauth:
firewall_names: [main]
# https://github.com/hwi/HWIOAuthBundle/blob/master/Resources/doc/2-configuring_resource_owners.md
resource_owners:
auth0:
type: oauth2
class: 'App\Auth0ResourceOwner'
client_id: "%env(AUTH0_CLIENT_ID)%"
client_secret: "%env(AUTH0_CLIENT_SECRET)%"
base_url: "https://%env(AUTH0_DOMAIN)%"
scope: "openid profile email"
security.yaml
security:
encoders:
App\Entity\Users:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\Users
property: username
oauth_hwi:
id: hwi_oauth.user.provider
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
provider: oauth_hwi
oauth:
resource_owners:
auth0: "/auth0/callback"
login_path: /login
failure_path: /login
default_target_path: /testPage
oauth_user_provider:
service: hwi_oauth.user.provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: /logout
# target: /login
access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# Everyone that logged in can go to /
- { path: '^/testPage', roles: [IS_AUTHENTICATED_FULLY] }
.env
AUTH0_CLIENT_ID=not-so-secret-but-secret
AUTH0_CLIENT_SECRET=secret
AUTH0_DOMAIN=dev-...
用户转储:
TestPageController.php on line 17:
HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser {#3742 ▼
#username: "testUser"
}
我希望这是可以理解的。感谢您的帮助。
看来您必须从正在使用的 oauth 服务注销,这里是 similar issue。
用代码解决:
src/Security/CustomLogoutSuccessHandler.php
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
class CustomLogoutSuccessHandler implements LogoutSuccessHandlerInterface
{
private $target;
public function __construct(string $target)
{
$this->target = $target;
}
public function onLogoutSuccess(Request $request)
{
return new RedirectResponse($this->target);
}
}
security.yaml
logout:
path: /logout
success_handler: App\Security\CustomLogoutSuccessHandler
services.yaml
services:
App\Security\CustomLogoutSuccessHandler:
arguments: ['%env(resolve:LOGOUT_TARGET_URL)%']
.env
LOGOUT_TARGET_URL=https://{yourAuth0AppDomain}.auth0.com/v2/logout?returnTo={yourRedirectURL}&client_id={secret}
使用 Github 问题中的代码会将您重定向 4 次。注销->路由->(.env)Auth0->路由。
使用上面显示的代码将您重定向 3 次。注销->Auth0->路由。只是一个小改进。
Code from this post.
基本信息:
我创建了一个测试应用程序来测试 SSO(单点登录)是否有效。我使用 Auth0 作为 SSO 提供商。 Symfony 4.4 作为应用程序框架。我使用了来自 Auth0 的 this 文章来创建基础知识。到目前为止我可以 login/logout.
问题:
当我登录一次(使用凭据),然后注销然后再次登录时,我立即使用之前使用的相同帐户登录。无需再次填写凭据。它似乎记得会话或以某种方式没有完全注销用户。我希望用户在注销后必须使用凭据再次登录。由于我的一些用户将使用一台计算机来执行应用程序(因此需要切换用户)。
可能 fix/Extra 信息:
根据那里 docs/community 我应该看看 this。但这似乎意味着我需要 API 调用来添加 ?federated
。安装示例不使用哪个(可能是图书馆为我做的)。此外,我在由 make:auth
(或 make:user
)生成的 SecurityController 中的注销函数不再执行代码。即使我更改了函数名称,它仍然会注销我。直到我 remove/change 它停止的路线名称。这可能非常糟糕,但也许如果我有机会在注销时执行 API 调用,我可以执行此 API 调用。
我能想到的最好的事情就是更改 symfony 中的一些设置或添加一些小代码以使其正确注销。但是我不知道怎么办。
我的代码:
SecurityController.php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
// Does not trigger at all. It does not stop the page but just continues to redirect and logout.
dump($this->get('session'));
dump($session);
dump("test");
exit();
throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
}
}
Auth0ResourceOwner.php
<?php
namespace App;
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericOAuth2ResourceOwner;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
class Auth0ResourceOwner extends GenericOAuth2ResourceOwner
{
protected $paths = array(
'identifier' => 'user_id',
'nickname' => 'nickname',
'realname' => 'name',
'email' => 'email',
'profilepicture' => 'picture',
);
public function getAuthorizationUrl($redirectUri, array $extraParameters = array())
{
return parent::getAuthorizationUrl($redirectUri, array_merge(array(
'audience' => $this->options['audience'],
), $extraParameters));
}
protected function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults(array(
'authorization_url' => '{base_url}/authorize',
'access_token_url' => '{base_url}/oauth/token',
'infos_url' => '{base_url}/userinfo',
'audience' => '{base_url}/userinfo',
));
$resolver->setRequired(array(
'base_url',
));
$normalizer = function (Options $options, $value) {
return str_replace('{base_url}', $options['base_url'], $value);
};
$resolver->setNormalizer('authorization_url', $normalizer);
$resolver->setNormalizer('access_token_url', $normalizer);
$resolver->setNormalizer('infos_url', $normalizer);
$resolver->setNormalizer('audience', $normalizer);
}
}
routes.yaml
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /connect
hwi_oauth_connect:
resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect
hwi_oauth_login:
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /login
auth0_login:
path: /auth0/callback
auth0_logout:
path: /auth0/logout
# controller: App/Controller/SecurityController::logout
hwi_oauth.yaml
hwi_oauth:
firewall_names: [main]
# https://github.com/hwi/HWIOAuthBundle/blob/master/Resources/doc/2-configuring_resource_owners.md
resource_owners:
auth0:
type: oauth2
class: 'App\Auth0ResourceOwner'
client_id: "%env(AUTH0_CLIENT_ID)%"
client_secret: "%env(AUTH0_CLIENT_SECRET)%"
base_url: "https://%env(AUTH0_DOMAIN)%"
scope: "openid profile email"
security.yaml
security:
encoders:
App\Entity\Users:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\Users
property: username
oauth_hwi:
id: hwi_oauth.user.provider
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
provider: oauth_hwi
oauth:
resource_owners:
auth0: "/auth0/callback"
login_path: /login
failure_path: /login
default_target_path: /testPage
oauth_user_provider:
service: hwi_oauth.user.provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: /logout
# target: /login
access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# Everyone that logged in can go to /
- { path: '^/testPage', roles: [IS_AUTHENTICATED_FULLY] }
.env
AUTH0_CLIENT_ID=not-so-secret-but-secret
AUTH0_CLIENT_SECRET=secret
AUTH0_DOMAIN=dev-...
用户转储:
TestPageController.php on line 17:
HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser {#3742 ▼
#username: "testUser"
}
我希望这是可以理解的。感谢您的帮助。
看来您必须从正在使用的 oauth 服务注销,这里是 similar issue。
用代码解决:
src/Security/CustomLogoutSuccessHandler.php
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
class CustomLogoutSuccessHandler implements LogoutSuccessHandlerInterface
{
private $target;
public function __construct(string $target)
{
$this->target = $target;
}
public function onLogoutSuccess(Request $request)
{
return new RedirectResponse($this->target);
}
}
security.yaml
logout:
path: /logout
success_handler: App\Security\CustomLogoutSuccessHandler
services.yaml
services:
App\Security\CustomLogoutSuccessHandler:
arguments: ['%env(resolve:LOGOUT_TARGET_URL)%']
.env
LOGOUT_TARGET_URL=https://{yourAuth0AppDomain}.auth0.com/v2/logout?returnTo={yourRedirectURL}&client_id={secret}
使用 Github 问题中的代码会将您重定向 4 次。注销->路由->(.env)Auth0->路由。
使用上面显示的代码将您重定向 3 次。注销->Auth0->路由。只是一个小改进。
Code from this post.