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.
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
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