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
Related
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)
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.
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
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.
Trying to use both bundles with latest Symfony (V:2.7.2).
FOSOauth is set and works fine, but adding HWIOAuthBundle isn't so trivial. Following the instruction in native Read.me brought me to this:
The service "hwi_oauth.security.oauth_utils" has a dependency on a
non-existent service "hwi_oauth.resource_ownermap.api".
How to setup this two together?
It seems you haven't configured properly oauth section in the firewall (security.yml file) you want HWIOAuthBundle to work with.
For example, with Facebook:
// app/config/config.yml
hwi_oauth:
firewall_name: main
resource_owners:
facebook:
type: facebook
...
Then you need to configure main firewall
// app/config/security.yml
main:
pattern: ^/
oauth:
resource_owners:
facebook: "/login/check-facebook"
oauth_user_provider:
service: my_custom_oauth_user_provider
...
Don't forget to declare facebook login-check route
// app/config/routing.yml
facebook_login:
path: /login/check-facebook
and you also need to create a user provider (the bundle itself has some built-in providers that you can extend and modify) and register it as a service
// app/config/services.yml
my_custom_oauth_user_provider:
class: AppBundle\Security\OAuthUserProvider
As your question is how to setup HWIOAuthBundle with FOSOAuthServerBundle, there is a very complete guide of how to achieve this: A way to integrate FosUserBundle and HWIOAuthBundle
You need to add new firewall (e.g. secured_area) with authentication way "oauth".
For example:
security:
firewalls:
secured_area:
anonymous: ~
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
my_custom_provider: "/login/check-custom"
my_github: "/login/check-github"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
You can find this info here