gpt4 book ai didi

php - 如何使用 FOSUserBundle 创建 "two"(聊天和管理)或更安全的区域

转载 作者:搜寻专家 更新时间:2023-10-31 21:26:53 24 4
gpt4 key购买 nike

我在 Symfony 2.8.x 应用程序中工作,我需要设置两个安全区域:chatadmin。这意味着 chatadmin 将使用相同的登录模板(如果可能的话,我不需要为此设置不同的模板)。我在google 之前在这里提问,发现了一些相关的东西,我读了很多关于这个主题的帖子:1 , 2 , 3 , 4只是作为他们的一个例子,但我做错了什么,因为我无法正常工作。这就是 /app/config/security.yml 的样子(只是防火墙和 access_control 代码段):

security:
....
firewalls:
admin:
pattern: /admin/(.*)
anonymous: ~
form_login:
provider: fos_userbundle
csrf_provider: security.csrf.token_manager
login_path: fos_user_security_login
check_path: fos_user_security_check
use_forward: true
always_use_default_target_path: true
default_target_path: /admin
target_path_parameter: _target_path
use_referer: true
remember_me: true
logout:
target: /admin
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /
chat:
pattern: ^/chat/(.*)
anonymous: ~
form_login:
provider: fos_userbundle
csrf_provider: security.csrf.token_manager
login_path: fos_user_security_login
check_path: fos_user_security_check
use_forward: true
always_use_default_target_path: true
default_target_path: /chat
target_path_parameter: _target_path
use_referer: true
remember_me: true
logout: ~
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /

access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }

- { path: ^/chat/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }

- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }

现在这是我的包在 app/config/routing.yml 的配置:

platform_chat:
resource: "@PlatformChatBundle/Controller/"
type: annotation
prefix: /chat/
options:
expose: true

platform_admin:
resource: "@PlatformAdminBundle/Controller/"
type: annotation
prefix: /admin/
options:
expose: true

对于 FOSUserBundle 我已经尝试了这两个(都没有成功,并且一次都成功):

#FOSUser
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"



#FOSUser
# this second causes doubts to me since I think I will need
# to repeat the same routes for chat prefix but I'm not sure at all
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
prefix: /admin

fos_user_profile:
resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
prefix: /admin/profile

fos_user_register:
resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /admin/register

fos_user_resetting:
resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix: /admin/resetting

fos_user_change_password:
resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix: /admin/profile

我已经覆盖了位于 app/Resources/FOSUserBundle/views/Security/login.html.twig 的登录模板。 (如果需要源代码,我可以提供 ommit,因为不要让帖子比现在更长)。

当我调用 URL:http://domain.tld/app_dev.php/admin 并尝试登录时,我收到了这个错误:

Translation not found. Context: { "id": "Symfony\Component\Security\Core\Exception\BadCredentialsException: Bad credentials. in /var/www/html/platform-cm/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php:90\nStack trace:\n#0

(如果需要,我可以提供完整的堆栈跟踪)

这对我来说很奇怪,但可能是由于配置错误造成的,因为我已经仔细检查了凭据。

当我调用 URL:http://domain.tld/app_dev.php/chat 并尝试登录时,我得到了 Access Denied 但这是正确的,因为我是重定向到 http://domain.tld/app_dev.php/admin/。任何人都可以给我一些关于这个配置的帮助吗?我因此卡住了无法前进

第二种方法

这是基于@heah 建议使用监听器的第二种方法,但也不起作用我仍然收到相同的“凭据错误”消息并且根本无法登录。我已将 routing.yml 改回为:

#FOSUser
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"

我已将 security.yml 改回为:

安全性: ... 防火墙: 行政: 模式:^/ 匿名:~ 表单登录: 供应商:fos_userbundle csrf_provider: security.csrf.token_manager 登录路径:fos_user_security_login check_path: fos_user_security_check

            # if true, forward the user to the login form instead of redirecting
use_forward: true

# login success redirecting options (read further below)
always_use_default_target_path: true
default_target_path: /admin
target_path_parameter: _target_path
use_referer: true
remember_me: true
logout:
target: /admin
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
path: /

access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }

- { path: ^/chat/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/chat/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }

- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }

然后我按照 app/config/config.yml 中的建议为事件 security.interactive_login 定义了一个监听器:

parameters:
account.security_listener.class: PlatformAdminBundle\Listener\SecurityListener

然后在app/config/services.yml:

services:
account.security_listener:
class: %account.security_listener.class%
arguments: ['@security.context', '@session']
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

最后是 src/PlatformAdminBundle/Listener/SecurityListener.php 中的类定义:

namespace PlatformAdminBundle\Listener;

use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class SecurityListener
{

public function __construct(SecurityContextInterface $security, Session $session)
{
$this->security = $security;
$this->session = $session;
}

public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$user = $this->security->getToken()->getUser();
var_export($user);
}

}

我再次遇到同样的问题,也许我做错了什么,我没有看到,但我接受任何想法。这里可能出了什么问题?

第三种方法

我已经对我的代码进行了审查,并主要根据@heah 的建议对其进行了轻微更改。所以,现在 security.yml 如下:

access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }

- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }

services.yml 的变化基本上修复了参数,因为 security.context 在 Symfony 2.6+ 中被拆分了,尽管我根本没有使用它:

services:
...
account.security_listener:
class: %account.security_listener.class%
arguments: ['@security.authorization_checker']
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

最后是类 PlatformAdminBundle/Listener/SecurityListener.php 的变化:

namespace Clanmovil\PlatformAdminBundle\Listener;

use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class SecurityListener
{

public function __construct(AuthorizationCheckerInterface $authorizationChecker)
{
$this->security = $authorizationChecker;
}

public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
if ($this->security->isGranted('ROLE_ADMIN')) {
// this is something for testing
throw new AccessDeniedException(
'Access Denied. You are ADMIN'
);
} elseif ($this->security->isGranted('ROLE_CHATTER')) {
// this is something for testing
throw new AccessDeniedException(
'Access Denied. You are CHATTER'
);
}
}
}

当我以 ROLE_CHATTER 用户身份登录时,一切似乎都正常,因为我遇到了 AccessDenied 异常,但是当我尝试以 ROLE_ADMIN 用户身份登录时,它停止工作,我回到最初的错误:Bad credentials,这是为什么?我快疯了!!

最佳答案

您需要启用翻译:

# config.yml

framework:
translator: ~
...

fos_user:
db_driver: orm # or mongodb|couchdb|propel
firewall_name: global
user_class: AppBundle\Entity\User

参见 https://symfony.com/doc/master/bundles/FOSUserBundle/index.html

#security.yml

security:
firewalls:
# ...
global:
pattern: ^/
anonymous: true
provider: fos_userbundle
form_login:
csrf_token_generator: security.csrf.token_manager
remember_me: true
default_target_path: root
logout:
path: fos_user_security_logout
target: root
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds

access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

- { path: ^/chat/, role: ROLE_CHATTER }
- { path: ^/admin/, role: ROLE_ADMIN }

参见 http://symfony.com/doc/current/components/security/authentication.html

您还应该使用相同的防火墙,因为它们共享相同的配置,并且您已经根据用户角色定义了访问控制。

您只需要为“/”创建一个核心 Controller :

# routing.yml
root:
path: /
defaults: { _controller: Your\Namespace\Controller\RootController::rootAction }

namespace Your\Namespace\Controller;

use Symfony\Bundle\FrameworkBundle\Controller;

class RootControler extends Controller
{
public function rootAction()
{
$security = $this->get('security.authorization_checker');

if ($security->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('your_admin_root');
}

if ($security->isGranted('ROLE_CHATTER')) {
return $this->redirectToRoute('your_chatter_route');
}

return $this->redirectToRoute('fos_user_security_login');
}
}

关于php - 如何使用 FOSUserBundle 创建 "two"(聊天和管理)或更安全的区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34756244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com