Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
295 views
in Technique[技术] by (71.8m points)

php - How to overwrite a class from the Security Component?

I am using Basic Auth in my API (Silex), an endpoint receives user+pw from client, validates the user via basic auth and then returns the token to be used for further requests. Now when my app makes an AJAX call, if the credentials are right, everything works smooth. If the credentials are wrong, the API returns a 401 and a set WWW-Authenticate header. This causes the browsers to automatically show the default browser login form.

I don't want that to happen. In StackOverflow, they say the only two solutions are to either return a 400 instead of a 401, or to change the WWW-Authenticate header to something like 'FormBased'.

Both the statusCode is set to 401 and the WWW-Authenticate to "Basic ..." in the BasicAuthenticationEntryPoint.php in the Security Component.

If I apply the changes there, it works... but I need to have that as part of my project ofc... How should I overwrite SymfonyComponentSecurityHttpEntryPointBasicAuthenticationEntryPoint.php to adapt it to my needs? any idea if there's a workaround? I understand this should be a very common problem, how is it generally solved?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok so here's what I did in case someone wonders:

First in my Security folder, I created my own version of the BasicAuthenticationEntryPoint.php

<?php

/*
 * Redefinition of the Symfony's BasicAuthenticationEntryPoint
 */

namespace multikanbanmultikanbanSecurityHttpEntryPoint;

use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentSecurityHttpEntryPointAuthenticationEntryPointInterface;

/**
 * BasicAuthenticationEntryPoint starts an HTTP Basic authentication.
 *
 * @author Fabien Potencier <[email protected]>
 */
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;
    }
}

Note that I did two things:

  1. Add the use for the AuthenticationEntryPointInterface.
  2. Change the WWW-Authenticate value to 'FormBased', this being the actual modification to the original file, so that the browsers don't show the default prompt when the server returns a 401 Unauthorized. (You could also return a 400 but then you wouldn't really be complying with the standard)

Second, I defined the service in my Silex Application like so:

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

'main' being my firewall name.

Obviously, I also added the use at the top of the Application.php:

use multikanbanmultikanbanSecurityHttpEntryPointBasicAuthenticationEntryPoint;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...