FOSRestBundle ignores unauthorized challenge config - php

I am creating a REST-API and currently have Basic Auth defined as authentication.
Symfony firewall config:
secured_area:
pattern: ^/
anonymous: false
http_basic:
realm: "Secured Basic Auth Area"
This leads to the correct behaviour if I do an unauthenticated request I get the correct header:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Secured Basic Auth Area"
...
But the problem is now that if I do a request via the browser i always get the Basic Auth popup being shown. To prevent this I though I could use the unauthorized_challenge config of the FOSRestBundle to change to custom authenticate challenge. Tough it does not change the returned header.
Config for rest bundle:
fos_rest:
unauthorized_challenge: "xxxBasic realm=\"Foo Area\""
access_denied_listener:
json: true
FOSRestBundle version is 1.4.2, Symfony version is 2.3.18.
Any idea what could be the problem that the FOSRestBundle setting is ignored?

Got it solved, the problem was:
I had an kernel.request listener which was throwing an AuthenticationException, this seemed to lead to the problem that further propagation of the event failed and the RestBundle listener was not properly called.
For completeness, after that got fixed I encountered another problem that the response always contained the Exception as HTML output. To solve this I also had to configure the FOSRestBundle exception controller in the Twig config.
My app/config.yml looks now like this (for the appropriate parts):
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
# Handle expections via the FOSRestBundle
exception_controller: 'FOS\RestBundle\Controller\ExceptionController::showAction'
fos_rest:
unauthorized_challenge: "xxxBasic realm=\"Foo Area\""
access_denied_listener:
json: true

Related

Platform api problem - returns all Exceptions as Json

After installing api platform there was a problem with deleting the cache, a message popped up:
Service "api_platform.error_listener": Parent definition "exception_listener" does not exist.
I fixed this error by adding:
api_platform.error_listener:
class: apiPlatform.error_listener.
arguments:
$controller:"#api_platform.action.exception"
$logger: "#logger"
$debug: "%kernel.debug%"
to the services.yaml file
However, now all Exceptions are returned as json. How to set only exceptions for api to be json (/api), while all others I would like to restore Twig Exception.

Troubles with firewall symfony 6. Error: Class "" used for service "security.listener.user_checker.integration" cannot be found

I'm trying to update symfony from 3.4 to 6.0.1
And i got an error
Class "" used for service "security.listener.user_checker.integration" cannot be found.
I have this error for each blocks in firewalls section
integration:
pattern: ^/integration
host: %base_host%
stateless: true
custom_authenticators:
- integration.authenticator.token
provider: integration_provider
I checked https://github.com/symfony/symfony/blob/6.0/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php#L119
and
https://github.com/symfony/symfony/blob/6.0/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php#L472
So ChildDefinition has no class(but has parent)
And I can't understand how it should work. Which class should be returned in RegisterListenersPass and where it should be set
I found a temporary solution.
It does not resolve the base problem, and I still want to figure out with my problem.
But now I can describe service like
security.listener.user_checker.integration:
class: Symfony\Component\Security\Http\EventListener\UserCheckerListener
And the error gone.

No token from TokenStorage on test environment

I want to include the logged in user's id to my logger.
So I have added a monolog.processor that adds the user id to the 'extra'-portion of the record, and added a custom format string that displays the id.
On my dev environment this works (mostly) as expected, but on the test environment it does not work at all, the TokenStorage always returns null on getToken().
There are no specific security configs for dev or test. The biggest differences between the configs is this part:
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
I have add this to my dev config but could not reproduce the symptoms. I can only reproduce by making symfony think it really is in test.
To be honest, I don't even know where to begin to debug this.
Any ideas what might be causing this behaviour?
Any ideas how I could debug this so I can get to an answer?
In order to have a token you should be inside on of the symfony firewalls.
If any of the firewalls aren't matched by the URI, symfony security is not triggered and you will not have a token.
If it is a public area allow anonymous users from root '/*' and use ACL for the rest of the URI (or actions). Anonymous users will have the role IS_AUTHENTICATED_ANONYMOUSLY
# app/config/security.yml
security:
firewalls:
main:
pattern: ^/
anonymous: ~
Documentation:
http://symfony.com/doc/current/security.html

Symfony2 API Key Authentication - No route found for

I followed the documentation, and this is how my code is organized:
src/Company/AuthBundle/Security/ApiKeyAuthenticator.php
src/Company/AuthBundle/Security/ApiKeyUserProvider.php
(they are the same as sample classes in doc)
# File: services.yml
apikey_authenticator:
class: Company\AuthBundle\Security\ApiKeyAuthenticator
public: false
# File: security.yml
firewalls:
api:
pattern: ^/api
stateless: false
simple_preauth:
authenticator: apikey_authenticator
provider: fos_userbundle
security: false
anonymous: true
And now, If I try to access e.g. http://symfony-project.dev/api?apikey=somekey, I got the following error:
No route found for "GET /api"
Any idea what's wrong?
The error message is fairly clear really - you haven't defined a route for a GET request for '/api'.
The security component you've configured takes care of authentication and granting access, but it does not control any logic specific to your application. You must create a controller and a route for requests like this.
You can see your currently defined routes with $ php app/console debug:router - if you've tried to define a route, that will help you debug it. If not, you must create one.

Failed user login on production server using Symfony framework (Authentication request could not be processed due to...)

I'm using Symfony for a project and I have been trying to get the login to work on production server with no success for the past 2 days. I keep getting the error
Authentication request could not be processed due to a system problem.
I have followed the guide here (http://symfony.com/doc/current/cookbook/security/entity_provider.html) to setup loading users from database.
My security.yml file:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
Acceptme\UserBundle\Entity\User: plaintext
role_hierarchy:
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
in_memory:
memory:
users:
patricia:
password: patricia
roles: 'ROLE_ADMIN'
users:
name: user_provider
entity: { class: AcceptmeUserBundle:User, property: username }
firewalls:
user_area:
pattern: ^/
anonymous: ~
provider: user_provider
form_login:
login_path: login_route
check_path: _login_check
default_target_path: homepage
dev:
pattern: ^/(_(profiler|wdt|error)|css|images|js)/
security: false
default:
anonymous: ~
http_basic: ~
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
My SecurityController.php:
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Security\Core\SecurityContext;
class SecurityController extends Controller
{
/**
* #Route("/login", name="login_route")
* #Template("security/login.html.twig")
*/
public function loginAction(Request $request)
{
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $request->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
return array(
'last_username' => $request->getSession()->get(SecurityContext::LAST_USERNAME),
'error' => $error,
);
}
/**
* #Route("/login_check", name="_login_check")
*/
public function securityCheckAction()
{
// this controller will not be executed,
// as the route is handled by the Security system
}
}
I have tried uploading the project on 2 different web hosts (FatCow & GoDaddy) and the problem remains. Locally i am using PHP 5.4.19 (FatCow uses 5.3.2 and GoDaddy uses 5.4.37). Keep in mind that when working on localhost with XAMPP everything works fine!
I've confirmed that PDO is enabled in both cases. I've confirmed that the database username, password and host are correct in the parameters.yml file. Error logs on both local and remote servers show nothing.
I have followed all directions from this previous post Deploying Symfony2 app getting fosuserbundle errors and still no success.
It looks like that the error:
Authentication request could not be processed due to a system problem.
is too generic and does not tell anything about where the problem is (there is an issue opened about this matter here).
I solved my issue by checking the logs and see what happened (in var/logs/dev.log), hoping this helps someone.
In my specific case, there was a wrong parameter in parameters.yml about database connection. But, again, the error is too generic and does not necessarily imply that the problem is related with database connection.
This problem can be fixed running command: php bin/console cache:clear --env=prod --no-debug
UPDATE: Issue solved. The issue was that a table in the entity php file was named with upper case letters while the database table was named with lower case. +1 to ClémentBERTILLON for pointing in the right direction, namely prod.log
AS #ShinDarth mention it. It is too generic and log inspection will help people in our case to get throught this.
If it can help in my situation it was :
After an SonataUserBundle installation in SF3, I had to
bin/console doctrine:schema:update --force
My context is particular, I have had already installed and used FOSUserBundle before to install SonataUserBundle. (Because of SF3 compatibility with FOSUser/SonataUSer...
Database have been taken 16 queries after that. Working great.
You probably used the template given by Symfony docs here :
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
Which actually gives you this error message. The most simple and reliable way to fix this issue is to replace this line by the following :
<div class="alert alert-danger">{{ error }}</div>
Which will give you the full stack-trace for your error and (hopefully) help you debug your application. Don't forget to revert this before going to production!
In my case, I changed user entity and then I forgot to update table.
for table update:
php bin/console doctrine:schema:update --force
Currently there is a bug in Symfony and on production IF during authentication system error occurs (missing table, missing column or any other exception) - it's logged as INFO instead of ERROR and with default error logging options it's not logged at all.
https://github.com/symfony/symfony/pull/28462
I think there are two options right now - temporary log everything (including INFO) on production until you find the real error.
Second option: use this patch or debug directly on production.
I'm sure that this error is too generic. In my case, The follow is incorrect:
class: App/Entity/User;
Correction:
class: App\Entity\User;
This solution is correct for me: https://stackoverflow.com/a/39782535/2400373
But If you do not have access to the terminal, you can enter the server and delete the folders that are inside var/cache.
Another solution if you have access to the console is to type
#rm -rf var/cache/*
or
$sudo rm -rf var/cache/*
this solution works on symfony 3
In my case the issue was fixed by correcting a typo in connection details in the .env file.
Another possible cause could be MySQL Server. In my case I forgot to start MAMP / MySQL Server and Symfony resulted with this message.
It's a bug on Symfony 5.3 that happens only on the Internet server. On my local server, no problem. Try to downgrade to 4.5 or 5.0. Then try the authentication again. In my case, the token to authenticate the user can't create and is unable to make a query to the database to validate that the user password is correct.
To extend on answer given by gogaz, Symfony's security bundle doesn't seem to be logging these errors by default as (I guess) it's assumed they will be authentication issues.
It might be worth it to inject a logger into your action and (conditionally) log the errors.
public function loginAction(AuthenticationUtils $authenticationUtils, LoggerInterface $logger): Response
{
if (($error = $authenticationUtils->getLastAuthenticationError()) && ($error instanceof AuthenticationServiceException)) {
$logger->critical($error->getMessage(), $error->getTrace());
}
...
}
Do note that you might have to extend the logging if your security implementation can throw other error types you may want to log.

Categories