代码之家  ›  专栏  ›  技术社区  ›  mezod

如何覆盖安全组件中的类?

  •  0
  • mezod  · 技术社区  · 11 年前

    我在我的API(Silex)中使用基本身份验证,端点从客户端接收user+pw,通过基本身份验证验证用户,然后返回令牌以用于进一步请求。现在,当我的应用程序发出AJAX调用时,如果凭据正确,一切都会顺利进行。如果凭据错误,API将返回401和设置的WWW-Authenticate标头。这会导致浏览器自动显示默认的浏览器登录表单。

    我不想这样。在StackOverflow中,他们说只有两种解决方案是返回400而不是401,或者将WWW-Authenticate标头更改为类似于“FormBased”。

    在安全组件的BasicAuthenticationEntryPoint.php中,statusCode设置为401,WWW Authenticate设置为“Basic…”。

    如果我在那里应用这些更改,它会起作用。。。但我需要把它作为我的项目的一部分。。。我应该如何覆盖Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint.php以使其适应我的需要?知道有没有变通办法吗?我知道这应该是一个非常普遍的问题,通常是如何解决的?

    1 回复  |  直到 11 年前
        1
  •  0
  •   mezod    11 年前

    好吧,这是我在万一有人怀疑时所做的:

    首先在我的Security文件夹中,我创建了自己版本的BasicAuthenticationEntryPoint.php

    <?php
    
    /*
     * Redefinition of the Symfony's BasicAuthenticationEntryPoint
     */
    
    namespace multikanban\multikanban\Security\Http\EntryPoint;
    
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
    
    /**
     * BasicAuthenticationEntryPoint starts an HTTP Basic authentication.
     *
     * @author Fabien Potencier <fabien@symfony.com>
     */
    class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface
    {
        private $realmName;
    
        public function __construct($realmName)
        {
            $this->realmName = $realmName;
        }
    
        /**
         * {@inheritdoc}
         */
        public function start(Request $request, AuthenticationException $authException = null)
        {
            $response = new Response();
            $response->headers->set('WWW-Authenticate', 'FormBased');
            $response->setStatusCode(401);
    
            return $response;
        }
    }
    

    请注意,我做了两件事:

    1. 添加AuthenticationEntryPointInterface的用法。
    2. 将WWW-Authenticate值更改为“FormBased”,这是对原始文件的实际修改,这样当服务器返回401未授权时,浏览器不会显示默认提示。(你也可以返回400,但这样你就不会真正遵守标准了)

    其次,我在我的Silex应用程序中这样定义了服务:

        $this['security.entry_point.main.http'] = $this->share(function() {
            return new BasicAuthenticationEntryPoint('main');
        });
    

    “main”是我的防火墙名称。

    显然,我还在Application.php的顶部添加了用法:

    use multikanban\multikanban\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;