You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sulu 2.6单站点自定义控制器登录保护及缓存问题问询

Sulu 2.6 单站点SSO登录验证+缓存问题解决方案指引

一、单站点专属登录保护配置

  • 基于Symfony安全组件,给目标站点单独配置防火墙,避免影响其他3个站点:
    在security.yaml中新增专属防火墙,通过站点域名或Sulu站点标识匹配:
    security:
        firewalls:
            target_site_sso:
                pattern: ^/target-site-prefix/
                host: your-target-site-domain.com
                # 或用Sulu站点唯一标识:sulu_site: your_target_site_key
                guard:
                    authenticators:
                        - App\Security\SsoSimpleAuthenticator
                stateless: false # 若SSO是会话式则设为false,无会话则设为true
    
  • 给自定义控制器的路由添加目标站点前缀,确保路由仅匹配该站点。

二、解决缓存问题

  • 直接在控制器方法上禁用Sulu默认缓存,添加注解:
    use Sulu\Bundle\HttpCacheBundle\Cache\SuluHttpCache;
    
    /**
     * @SuluHttpCache(expires="now", public=false)
     */
    public function yourCustomAction(Request $request)
    {
        // 控制器逻辑
    }
    
  • 或者手动设置响应头强制不缓存:
    $response->headers->set('Cache-Control', 'no-cache, no-store, must-revalidate');
    
  • 放弃全局生效的User Context Caching,仅针对目标站点做缓存排除。

三、简化SSO二元验证(无需Sulu后端用户)

  • 实现轻量Guard认证器,仅验证SSO Token有效性,无需创建Sulu用户实体:
    namespace App\Security;
    
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\User\UserProviderInterface;
    use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class SsoSimpleAuthenticator extends AbstractGuardAuthenticator
    {
        private $ssoValidator;
    
        public function __construct(YourSsoValidationService $ssoValidator)
        {
            $this->ssoValidator = $ssoValidator;
        }
    
        public function supports(Request $request)
        {
            // 仅在目标站点生效
            return $request->attributes->get('_sulu_site') === 'your_target_site_key';
        }
    
        public function getCredentials(Request $request)
        {
            // 从请求获取SSO Token(示例从Header取,可根据实际调整)
            return $request->headers->get('X-SSO-Token');
        }
    
        public function getUser($credentials, UserProviderInterface $userProvider)
        {
            // 调用SSO服务验证Token有效性
            if (!$this->ssoValidator->isTokenValid($credentials)) {
                throw new AuthenticationException('Invalid SSO token');
            }
            // 返回虚拟用户,仅用于标识登录状态
            return new class implements UserInterface {
                public function getRoles() { return ['ROLE_SSO_USER']; }
                public function getPassword() { return null; }
                public function getSalt() { return null; }
                public function eraseCredentials() {}
                public function getUserIdentifier() { return 'sso_authenticated_user'; }
            };
        }
    
        public function checkCredentials($credentials, UserInterface $user)
        {
            return true; // 已在getUser中完成Token验证
        }
    
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
        {
            return null; // 继续执行控制器逻辑
        }
    
        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
        {
            return new Response('Unauthorized', Response::HTTP_UNAUTHORIZED);
        }
    
        public function start(Request $request, AuthenticationException $authException = null)
        {
            // 未登录时跳转SSO登录页或返回提示
            return new Response('Please log in via SSO', Response::HTTP_UNAUTHORIZED);
        }
    
        public function supportsRememberMe()
        {
            return false; // 根据需求调整
        }
    }
    
  • 在控制器中通过授权检查实现二元验证:
    use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
    
    public function yourCustomAction(Request $request, AuthorizationCheckerInterface $authChecker)
    {
        if (!$authChecker->isGranted('ROLE_SSO_USER')) {
            throw new AccessDeniedException();
        }
        // 已登录后的业务逻辑
    }
    

四、核心注意事项

  • 防火墙规则必须精准匹配目标站点,防止影响其他站点。
  • 控制器必须禁用缓存,避免登录状态被缓存导致逻辑混乱。
  • 虚拟用户仅用于标识登录状态,无需关联Sulu用户系统,满足极简验证需求。

内容的提问来源于stack exchange,提问作者Andreas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 00:05:01