The error is just a basic one. A class does not exist, and the error is actually very right. The class indeed does not exist. We're now working on Multi-Tenancy for this project, and there is where it currently gives up. This is the error;
Class "App\Entity\User" does not exist
It is a ReflectionException. For this we did a few things.
We have the following folder structure for our Symfony API-Platform instance;
- Controller
- Messenger
- Entity
--- Main
--- Tenant
- Repository
- ....
And I bet that here is where the problem lies. The User Entity is not App\Entity\User. The Class is in the Main folder, so is named App\Entity\Main\User. However, when trying to use the app, it will always return in an HTTP 500, with the error message given above. It tries to find the class, which isn't there.
So, this is a bit different. We needed to change the provider for the authentication as stated in the Symfony Documentation. We did this by modifying the security.yaml as stated in the documentation.
providers:
database_users:
entity:
class: App\Entity\Main\User
property: email
However, it still tries to use the other Entity. We've search the project, and there is absolutely no reference. We've emptied the cache and rebuild the docker-container, all to no avail. It still is looking for the class, which is not there, but in another folder inside there.
Are we missing something? The error Stack Trace is that it appears in the autoload_runtime.php, but even when dumping and regenerating this, it has no avail.
Firewall from security.yaml
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
# this firewall applies to all URLs
pattern: ^/
lazy: true
# The user provider to use.
provider: database_users
Related
I have a symfony 5.3 installation with 2 security providers.
If I'm using the DEV environment I can login using users from both the providers, but when I change the environment to TEST or PROD I can only login using one of them.
If I add logging to my authenticator I see that I reach the function onAuthorizationSuccess with the right user on both cases, but if I'm on TEST or PROD, the page that I see is again the login page. If I switch between environments I can replicate the behaviour any time: dev ok, test and prod not passing from the login page for one of the providers. The other one ok in all the situations.
I understand that Symfony is working differently on dev than test or prod, but I'm not able to figure out what is the difference.
There are no errors on the logs and I have cache:clear a few times..
Is there any way I can debug this behaviour?
The behaviour changes completely if I'm on DEV or TEST/PROD environments. The test environment uses a .env.test copy of .env.dev, so it should'nt affect the result.
If I change .env to use DEV and clean cache it works: the 2 types of users can login, if I change .env to use TEST for example and clean cache again it doesn't work...
My security.yaml (relevant parts):
security:
chain_provider:
chain:
providers: [app_user_provider, sec_user_provider]
app_user_provider:
entity:
class: App\Entity\WebUser
property: login
sec_user_provider:
entity:
class: App\Entity\Security\User
property: login
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: lazy
provider: chain_provider
guard:
authenticators:
- App\Security\BasicAuthenticator
logout:
path: app_logout
I am using multiple users providers in my project.
My security.yml looks like this :
security:
...
firewalls:
usertype1:
pattern: ^/root/usertype1_area
provider: type1_provider
usertype2
pattern: ^/root
provider: type2_provider
...
Everything is working fine and I can't login with wrong user types at the right pattern, except that I noticed that if I throw an exception in one of my providers, say type1_provider , and try to log in with the /root/login path (which should use only type2_provider), Symfony is going through type1_provider as well as type2_provider, and I get an exception.
The same is also true with /root/usertype1_area/login when I throw at type2_provider.
This is a problem to me because I want to be able to access type2 login when the type1_provider is shut down.
Any guesses ? Is this normal behavior ?
EDIT : As pointed out by Alexander Keil, it was not clear in my question what I was trying to do
One of my providers relies on a 3d party service, and I want it to throw when this service is down, but I still want to be able to access the other login, which is not supposed to rely on the provider that is throwing. Is there a way I can achieve this ?
You can use the method "supportsClass" in your provider. Return false if the current user class does not support the loaded provider. See Symfony\Component\Security\Core\User\UserProviderInterface
I have application which base on logging users by FOSOAuthServerBundle and I want to test actions in this application.
So... In Sf2 are special config file for testing environment, config_test.yml and I've put this code:
security:
firewalls:
default:
anonymous: ~
In theory it should solve my problem, because this firewall allows anyone access any action. I've put it in config_test.yml, so it should work only then I'm testing application. Good solution, I was thinking.
But Sf threw this error:
You are not allowed to define new elements for path "security.firewalls". Please define all elements for this path in one config file.
My questions is:
How can I allow access actions without logging while testing application by PHPUnit?
You can't add/define new elements but you can modify them.
In config_test.yml instead default firewall use name of your real firewall used in security.yml.
And better will be using http_basic: ~ instead anonymous: ~ so your tests will can behave like real authenticated user.
Nice cookbook here: http://symfony.com/doc/2.8/cookbook/testing/http_authentication.html
I am trying to adjust FOSUserBundle to work with my Neo4j database and I cant seem to get it working. After a long time of trying to implement my own user system without any luck (Setting up NEO4j in Symfony2), I started trying to use the FOSUserBundle.
I have used the following articles and repositories:
https://github.com/ikwattro/Neo4jUserBundle
I have taken this and copied all of the files into my UserBundle. I have changed the namespaces.
I have taken the graph manager from here: https://github.com/ikwattro/KwattroNeo4jOGMBundle
For the rest, I have followed the FOSUserBundle documentation.
Now, when I go to the registration form, all fields appear and I can fill in my preferred credentials. This works. After I click on submit I get redirected to the success page, on which an alert overlay is displayed:
An error occurred while loading the web debug toolbar (500: Internal
Server Error). Do you want to open the profiler?
If I then enter the profiler, I can see that I have successfully been authorized and logged in as the user that I just created. The data is also successfully saved in my neo4j database.
The problem now is that if I go to any other page of my Symfony project, I am logged in as Anonymous again. And If I go to the login page, the form is displayed correctly, but it always returns: Invalid credentials.
I am guessing, that there is something wrong with my sessions or my security?
This is my security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
Neo4jUserBundle\Entity\User: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: neo4j.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: security.csrf.token_manager
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
I dont know if this information can help or is relevant, but in the profiler under the Request right after registration (when the user is still authenticated correctly) this is the session information:
Session Metadata
Key Value
Created Tue, 21 Jul 15 17:27:34 +0200
Last used Tue, 21 Jul 15 17:27:34 +0200
Lifetime 0
Session Attributes
Key Value
_csrf/authenticate A_H4Ul1XHFYoxQdOirdmbBQRRCJ01Xh8EkGeC6Y7xw0
_csrf/registration OAXAXhfhcN6z0WekMN0fk8zg4ikk5uCCZBlvhy8DyVY
_security.last_username test
_security_main C:74:"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":444:{a:3:{i:0;N;i:1;s:4:"main";i:2;s:404:"a:4:{i:0;C:32:"neo4jProxyUserBundle_Entity_User":192:{a:9:{i:0;s:60:"$2y$13$e49oj61cdjk88kk040wg8exlwqVzbdQB5IVNG18Wqcbe.EW8KXi72";i:1;s:31:"e49oj61cdjk88kk040wg8kcc4cg40c4";i:2;s:4:"test";i:3;s:4:"test";i:4;b:0;i:5;b:0;i:6;b:0;i:7;b:1;i:8;i:66;}}i:1;b:1;i:2;a:1:{i:0;O:41:"Symfony\Component\Security\Core\Role\Role":1:{s:47:"Symfony\Component\Security\Core\Role\Rolerole";s:9:"ROLE_USER";}}i:3;a:0:{}}";}}
Flashes
Key Value
success [0 => registration.flash.user_created, 1 => registration.flash.user_created, 2 => registration.flash.user_created, 3 => registration.flash.user_created, 4 => registration.flash.user_created, 5 => registration.flash.user_created, 6 => registration.flash.user_created, 7 => registration.flash.user_created, 8 => registration.flash.user_created]
Any help or hints would be appreciated.
UPDATE [21.07.2015]
I have now created a repository: https://github.com/JoranBeaufort/Neo4jUserBundle (I hope this works, the first time I have used GitHub)
I guess that there is something off with the session handling?
Another thing to point out is, that the dependency injection does not seem to do anything. I must be missing a few vital things.
It would be great to be able to offer a Neo4jUserBundle that works out of the box with FOSUserBundle and can be configured in the config file of the Symfony project. Great and vital would also be the authentication with the database (use username and password to connect to neo4j).
UPDATE [22.07.2015]
I have changed the bundlename and I think I have finally gotten the DependencyInjection to work. I'm not quite sure but I think I had a problem with how I named my classes.
I have also tried what you suggested with findUserById. I have written a controller which takes the route myapp.com/neo4juser/debug/finduserbyid/{id} and then uses the findUserById method to return the user. This is working. I have a user in my Neo4j-Database with an ID = 68 and an email=test#test.test. If I now enter myapp.com/neo4juser/debug/finduserbyid/68 the page is loaded displaying the right email of that user.
TWIG can be found here: https://github.com/JoranBeaufort/Neo4jUserBundle/blob/master/Resources/views/Debug/finduserbyid.html.twig
And the CONTROLLER here: https://github.com/JoranBeaufort/Neo4jUserBundle/blob/master/Controller/DebugController.php
The methods in the UserManager seem to be returning the desired objects.
Does this help in figuring out why the login does not work in any way? Does the serialization have anything to do with the error or the encryption type? Or could it be something to do with the CSRF? Any further hints?
UPDATE [23.07.2015]
When using in_memory as the provider and setting up an in_memory user, the login works. So now I have narrowed down the problem to the provider.
I am getting closer! Now the error in the dev.log file reads:
[2015-07-23 17:11:54] security.INFO: Authentication request failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): Bad credentials. at bla/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php:73, Symfony\\Component\\Security\\Core\\Exception\\UsernameNotFoundException(code: 0): Username \"test\" does not exist. at bla/src/Neo4jUserBundle/Security/UserProvider.php:42)"} []
Important is the part `Username "test" does not exist.I am guessing this means that something is not working in the user provider. Can anyone spot what the problem might be? The Provider which I am calling can be found here: https://github.com/JoranBeaufort/Neo4jUserBundle/tree/master/Security
Ok. I opened a PR for some tweaks, but I couldn't get the stuff working.
The tweaks I've done are adding the possibility to define a user and password for via the neo4j_user config, and load the services.yml file in the DI extension.
When I register a user, it is well created in the database. However for fetching a user, after some debug, I can see that the underlying client (neo4jphp combined with neo4j-php-ogm) are using the legacy indexes and it is throwing some errors at this stage.
I can not help further except to tell you to try to not use an ogm in the beginning and try with raw cypher queries.
I'm afraid trying to update both libraries used can be difficult in a first instance.
I would say the problem, as of 27/12/2015, is that UserManager, at line 73, does not return the found user (is a void function). I have not tried it yet and can´t for a few days, and maybe it´s an answer not sought anymore, but I´m pretty sure that´s the problem.
IDEs won´t find it a problems due to the #return tag:
* Finds a user by username
*
* #param string $username
*
* #return UserInterface
*/
public function findUserByUsername($username)
{
$this->findUserBy(array('usernameCanonical' => $this->canonicalizeUsername($username)));
}
I'm trying to figure out why I can't set multiple user providers into a single provider.
Currently I'm configuring ACL. For the user providers I want to have a couple of "hard-coded" users and users which would be loaded from a database.
Reading the documentation it's stated that you're not required to have two user providers - one for the in_memory users and one for the database users. You should be able to combine them into a single user provider (which is what I'm trying to do).
The suggested configuration is:
security:
providers:
main_provider:
memory:
users:
foo: { password: test }
entity:
class: Acme\UserBundle\Entity\User,
property: username
My configuration is:
security:
providers:
main_provider:
memory:
users:
foo: { password: test }
entity:
class: Company\EntitiesBundle\Entity\User,
property: username
Unfortunately I get this exception:
InvalidConfigurationException: Invalid configuration for path "security.providers.main_provider": You cannot set multiple provider types for the same provider
If I, however, set two different providers and chain them, it works without problems.
I can't figure out why this would happen? It's clearly stated in the documentation - you can accomplish this even more easily by combining the two sources into a single provider.
What am I missing here?
Why don't you chain providers? The documentation that you're referring states that you can use multiple user providers "...by creating a new provider that chains the two together".
http://symfony.com/doc/current/book/security.html#using-multiple-user-providers
Each authentication mechanism (e.g. HTTP Authentication, form login, etc) uses exactly one user provider, and will use the first declared user provider by default. But what if you want to specify a few users via configuration and the rest of your users in the database? This is possible by creating a new provider that chains the two together.
Now, all authentication mechanisms will use the chain_provider, since it's the first specified. The chain_provider will, in turn, try to load the user from both the in_memory and user_db providers.
All you have to do is to setup a chain provider.
# app/config/security.yml
security:
providers:
main_provider:
chain:
providers: [memory_provider, entity_provider]
memory_provider:
memory:
users:
foo: { password: test }
entity_provider:
entity:
class: Company\EntitiesBundle\Entity\User
property: username
Which Symfony version are you using? If 2.0, in 2.0 documentation the configuration is slightly different:
# app/config/security.yml
security:
providers:
main_provider:
users:
foo: { password: test }
entity: { class: Acme\UserBundle\Entity\User, property: username }
Notice the memory key missing.