Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony security return 401 response instead of redirect

I'm writing an ajax application with ajax authentication and now I started using the symfony security component in silex to handle authentication/authorization.
Doing a simple test with a simple configuration, I go to a protected area by the firewall and the response I get is a redirection to the /login page but what I need in my app is a 401 response with possible additional information(in headers or json body) on how to login.

$app['security.firewalls'] = [
    'api' => [
        'pattern' => '^/api',
        'logout' => ['logout_path'=>'/auth/logout'],
        'users' => $app->share(function(Application $app) {
            return new MyUserProvider();
        })
    ]
];

EDIT: I got a hint but I'm not sure how to use it. Implementing an entry point with AuthenticationEntryPointInterface I can tell the api how to answer unauthenticated requests and give the user the instructions needed to authenticate. That could be my 401 response with login instructions.

like image 758
olanod Avatar asked Sep 06 '13 16:09

olanod


2 Answers

What you need is a AuthenticationEntryPoint handler. Simple example:

class AuthenticationEntryPoint implements AuthenticationEntryPointInterface {

/**
 * Starts the authentication scheme.
 *
 * @param Request $request The request that resulted in an AuthenticationException
 * @param AuthenticationException $authException The exception that started the authentication process
 *
 * @return Response
 */
public function start(Request $request, AuthenticationException $authException = null)
{
    $array = array('success' => false);
    $response = new Response(json_encode($array), 401);
    $response->headers->set('Content-Type', 'application/json');

    return $response;
}
}

Register class as a service in services.xml file:

<parameters>
    <parameter key="authentication_entry_point.class">YourNameSpace\AuthenticationEntryPoint</parameter>
</parameters>

<services>
    <service id="authentication_entry_point" class="%authentication_entry_point.class%"/>
</services>

and make a small change in security.yml file:

security:
  firewalls:
    somename:
      entry_point: authentication_entry_point
like image 151
panK Avatar answered Oct 14 '22 12:10

panK


I was able to override the default entry point for the "form" type under the "api" firewall like this:

$app['security.entry_point.api.form'] = $app->share(function () use ($app) {
    return new MyAuthenticationEntryPoint();
});

Then it's just a matter of implementing the AuthenticationEntryPointInterface:

http://symfony.com/doc/current/components/security/firewall.html#entry-points

Have a look at the symfony implementation to get an idea:

Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint

Also, probably worth checking out the silex security service provider to see how they inject that into "security.entry_point.form._proto" the default implement.

Silex\Provider\SecurityServiceProvider
like image 42
ooXei1sh Avatar answered Oct 14 '22 12:10

ooXei1sh