How to override an array in my config file during test? - symfony

In dev and production, I use a PhpCas guard authenticator. During test, I want to replace it by another authenticator, a traditional login form authenticator.
So I have two config files. Here is the main security.yaml config file which works perfectly:
security:
# ...
firewalls:
# ...
#Main firewall
main:
anonymous: true
# We use Guard !
guard:
authenticators:
# This service is declared in services.yaml
# - app.security.login_form_authenticator
# CAS Server Cerbere
- phpcasguard.cas_authenticator
And I have a security.yaml in the test subdirectory which is perfectly loaded:
security:
firewalls:
#Main firewall
main:
guard:
authenticators:
# During test, I do not use CAS Server.
# This service is declared in services.yaml
- app.security.login_form_authenticator
But the app.security.login_form_authenticator is added. It does not replace the phpcasguard.cas_authenticator.
How to override guard.authenticator array in my test/security.yaml file ?
(I tried to used the guard.entry_point configuration key, but the two guard authenticators are loaded, so after the first authentication, my functional test tried to connect on CAS server. It is only changing the priority.)
(I tried to use key like the example below, but it does not replace it)
security:
firewalls:
#Main firewall
main:
guard:
authenticators:
# During test, I do not use CAS Server.
# This service is declared in services.yaml
0: app.security.login_form_authenticator
# AND in the main security file I used
0: phpcasguard.cas_authenticator

Related

Symfony 6 social login remember me not working

I have updated my project to Symfony 6, and now my google login is not working as before. The remember me token is not working if I close the browser. In 5.4, I had written my security.yaml like this :
google:
pattern: ^/connect/google
guard:
authenticators:
- App\Security\GoogleAuthenticator
logout:
path: app_logout
target: home
remember_me:
secret: "%env(GOOGLE_CLIENT_SECRET)%"
lifetime: 604800
always_remember_me: true
but now the cli tell me I need to change "guard". If I use custom_authenticator option, there are a lot of errors because I'm using SocialAuthenticator as you can see here : https://codeshare.io/Od84jx If I remove the google part from security.yaml I don't have error, and register and login are working, but not remember me token.
I finally succeeded, I share my solution for those who have the same problem.
So in symfony 5.4 to symfony 6.1, you need to use OAuth2Authenticator instead of SocialAuthenticator. You can follow the doc to write your GoogleAuthenticator : https://github.com/knpuniversity/oauth2-client-bundle#step-1-using-the-new-oauth2authenticator-class
Then you only need to add it in your custom_authenticator section in the security.yaml file. For example :
main:
switch_user: true
lazy: true
provider: app_user_provider
custom_authenticator:
- App\Security\LoginAuthenticator
- App\Security\GoogleAuthenticator
And then it will work if you already have your controller. (https://github.com/knpuniversity/oauth2-client-bundle#step-3-use-the-client-service)

401 Unauthorized : Bad Credentials on /login_check

I am developing an API with Symfony 4.2 and API Platform. I use the Lexik JWT bundle for JWT management.
I started by recovering my project thanks to GIT, then I installed the dependencies. I then configured the database (in the .env). I regenerated the private key and the public key and changed the pass_phrase in the .env (and also in the lexik configuration file).
I created the database, the schema and I also added the fixtures.
.env file :
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=fe2d9e035f82de508cfa67d0ae4720ed
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
#TRUSTED_HOSTS='^localhost|example\.com$'
###< symfony/framework-bundle ###
###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# Configure your db driver and server_version in config/packages/doctrine.yaml
DATABASE_URL=mysql://root:dimitri#localhost:3306/mydb
###< doctrine/doctrine-bundle ###
###> symfony/swiftmailer-bundle ###
# For Gmail as a transport, use: "gmail://username:password#localhost"
# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
# Delivery is disabled by default via "null://localhost"
MAILER_URL=null://localhost
###< symfony/swiftmailer-bundle ###
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN=*
###< nelmio/cors-bundle ###
###> lexik/jwt-authentication-bundle ###
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=dimitri
###< lexik/jwt-authentication-bundle ###
PROJECT_NAME="NAME"
PROJECT_VERSION="1.0"
API_URI="http://127.0.0.1:8000"
security.yaml file :
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
json_login:
check_path: /login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
anonymous: true
access_control:
- { path: ^/users/email$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
My project runs locally (on my pc), but when I deploy it on my VPS, I get this response: 401 Unauthorized - Bad credentials
Is that your VPS already configure to support https? From the documentation, you have to add SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 in your VirtualHost configuration(if you are using ubuntu server, it will be httpd.conf. I am using one) to support HTTP. if not it will strip away the authorization header.
For more info, refer to this LeixkJWTAuthentication Documentation

API-platform, protected root, trying to get client-generator working

I have an api-platform project. The roots are all protected by a login.
http://localhost:8888/docs does show the API documentation.
I kept getting 401 on the client generator, so, I made the following changes to security.yml
api:
pattern: ^/
security: false
provider: db_provider
stateless: true
anonymous: true
# guard:
# authenticators:
# - lexik_jwt_authentication.jwt_token_authenticator
That however generated a strange error:
generate-api-platform-client --generator vue http://localhost:8888 /src --resource legal_types
Error: Unable to find the URL for "http://localhost:8888/docs.jsonld#Entrypoint/user".
at _loop (/Users/xxx/.config/yarn/global/node_modules/#api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation.js:437:17)
at fetchEntrypointAndDocs.then._promise2.default.reject.api._Api2.default.resources (/Users/xxx/.config/yarn/global/node_modules/#api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation.js:459:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
pattern: ^/ matches nothing.
If you want to match anything you should go with ^.*$ but if you need all application to be under a secured firewall but only docs to be accessible in anonymous way, just put as first rule this pattern: ^docs and place everything else (/.*$) under secured firewall.

#Security Symfony annotation denies access - but states lack of authentication

Here's my annotation:
#Security("
request.getHost() == 'example.com' or
request.getHost() == 'google.com'
")
This works, but throws the following error:
Full authentication is required to access this resource.
This results in a 500 rather than a 403 as expected. The debug log:
DEBUG - Access denied, the user is not fully authenticated; redirecting to authentication entry point.
CRITICAL - Uncaught PHP Exception Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException: "Full authentication is required to access this resource." at /[path]/[to]/[project]/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php line 131
But there's no authentication point setup (or that needs to be setup):
security.yml:
firewalls:
dev:
pattern: ^/(_(profiler|wdt))/
security: false
no_auth:
pattern: ^/(|css|images|js|admin/login)/
security: false
admin:
anonymous: ~
pattern: ^/admin
guard:
authenticators:
- admin.form_login
logout:
path: admin_logout
main:
anonymous: ~
pattern: ^/
The annotation is on a controller that exists in ^/.
How do I get Symfony to throw a simple Access Denied?
When I do this on my admin controller, it behaves as expected - I don't get the lack of authentication, I get access denied. However, I need to have an unauthenticated resource, but limited by IP.

Installation HWIOAuthBundle?

I try 10 times to find out how to install HWIOAuthBundle But there is no enough documentation,
I install the Bundle and I follow exactly the documentation in Git But it shows me this error:
InvalidConfigurationException: Unrecognized options "anonymous" under "security.firewalls.secured_area.oauth"
Somehow I didn't understand the Part A) 'Have a user provider that implements'.What should I do?Or where can I find easy documentation
A) Have a user provider that implements OAuthAwareUserProviderInterface
The bundle needs a service that is able to load users based on the user response of the oauth endpoint. If you have a custom service it should implement the interface: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface.
The HWIOAuthBundle also ships with three default implementations:
OAuthUserProvider (service name: hwi_oauth.user.provider) - doesn't persist users
EntityUserProvider (service name: hwi_oauth.user.provider.entity) - loads users from a database
FOSUserBundle integration (service name: hwi_oauth.user.provider.fosub_bridge). Checkout the documentation for integrating HWIOAuthBundle with FOSUserBundle for more information: (todo)
what should I do here ?
You should replace/comment out the line of the service:
oauth_user_provider:
service: my.oauth_aware.user_provider.service
and then replace by:
oauth_user_provider:
oauth: ~
Source: https://github.com/hwi/HWIOAuthBundle/issues/72
Go further:
https://gist.github.com/danvbe/4476697
http://m2mdas.github.io/blog/2013/11/21/integrate-hwioauthbundle-with-fosuserbundle/
Ahh, seems like a typo in docs, could you move that anonymous 4 spaces lower to something like:
# app/config/security.yml
security:
firewalls:
secured_area:
anonymous: ~
oauth:
resource_owners:
facebook: "/login/check-facebook"
login_path: /login
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
Easy fix for this is to define a service like this :
In security.yml keep this :
oauth_user_provider:
service: my.oauth_aware.user_provider.service
In services.yml put this :
services:
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments:
userManager: "#fos_user.user_manager"
properties: ["pass properties as array"]
Thats it !

Resources