I am creating a SYMFONY application and I have to use differents users type: Clients, Expert and CustomerSuccess. Each user's type will have an authenticator's form. But, how can I create tokens with JWT on more than one entity?
Here is the Security.yaml file:
providers:
app_user_provider:
entity:
class: App\Entity\CustomerSuccess
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: false
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
jwt: ~
main:
lazy: true
provider: app_user_provider
This Security.yaml is working well but when I try to add another type of users, my API returns :
Not configuring explicitly the provider for the json_login authenticator on login firewall is ambiguous as there is more than one registered provider. (500 Internal Server Error).
Does anyone knows how to setup more than one users in SYMFONY's app with JWT token?
Thanks you ;)
Related
I successfully installed API Platform, it works well with all my entities.
Now i'm trying to add JWT authentication whith LexikJWTAuthenticationBundle, but when i send the request for login i get :
No route found for "GET /api/login"
My request :
http://localhost:8000/api/login?username=john&password=doe
I'm using Symfony 4, here is my security.yaml :
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
entity_provider:
entity:
class: App\Entity\User
property: username
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: entity_provider
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
provider: entity_provider
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
I think the JWT bundle works well because when i try to access a resource, i get :
{"code":401,"message":"JWT Token not found"}
I think it's just a matter of routing, but as i'm quite a newbie to Symfony i don't know what to do...
I already tried to change patterns, check path...
Any hint ?
EDIT : i added this in routes.yaml :
api_login_check:
path: /api/login
Now i have :
Unable to find the controller for path "/api/login". The route is wrongly configured.
More details from the logs :
WARNING
09:40:52
request Unable to look for the controller as the "_controller" parameter is missing.
ERROR
09:40:53
request Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "Unable to find the controller for path "/api/login". The route is wrongly configured."
Check this link https://github.com/symfony/symfony-docs/pull/7081/files#diff-7f5c7908922a550bda01ab86f19f3938R119
You have to send your request to http://localhost:8000/api/login with a json body like this
{"username": "john","password": "doe"}
Also I recommend to read this "How to Build a JSON Authentication Endpoint" https://symfony.com/doc/current/security/json_login_setup.html
Thanks
Thanks lvillarino, i already tried that without success but i think i made other mistake then... I tried again as i was quite sure that was the good direction and now it works !
This is my final configuration, maybe it will help someone...
FYI, i'm using email/password as credentials.
security.yaml
providers:
entity_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: entity_provider
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
main:
pattern: ^/
provider: entity_provider
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
encoders:
App\Entity\User:
algorithm: bcrypt
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
routes.yaml
api_login_check:
path: /api/login
I tried to login to my api using Postman using this url :
http://localhost:8000/api/login
On the headers section i have :
Accept : application/json
Content-type: application/json
And on the body section (raw) :
{
"email":"john#doe.fr",
"password":"mypass"
}
The token is successfully generated and functional, it is accepted as Bearer in further api calls.
More information : i had problems with private and public keys generated using PuttyGen on windows, i always had bad credentials when using the generated token. I had to generate them on a linux environment using openssl, and now it works.
Last information : i installed LexikJWTAuthenticationBundle with composer, i used the passphrase generated in .env file to generate the keys, as it's not very well explained in the installation process.
I'm in a bad situation for about 3 days, I'm trying to make a simple auth & register app, but I'm always getting this 500 error when using the token I'm generating :
Unable to verify the given JWT through the given configuration. If the "lexik_jwt_authentication.encoder" encryption options have been changed since your last authentication, please renew the token. If the problem persists, verify that the configured keys/passphrase are valid.
I was wondering what couldn't be good actually, here's my config :
In parameters.yml
jwt_public_key_path: '%kernel.root_dir%/../var/jwt/public.pem'
jwt_private_key_path: '%kernel.root_dir%/../var/jwt/private.pem'
jwt_key_pass_phrase: pass
jwt_token_ttl: 3600
The config.yml
lexik_jwt_authentication:
private_key_path: '%jwt_private_key_path%'
public_key_path: '%jwt_public_key_path%'
pass_phrase: 'pass'
token_ttl: '36000'
token_extractors:
authorization_header: # look for a token as Authorization Header
enabled: true
prefix: Bearer
name: Authorization
cookie: # check token in a cookie
enabled: false
name: BEARER
query_parameter: # check token in query string parameter
enabled: false
name: bearer
The security.yml
```
firewalls:
main:
pattern: ^/
anonymous: true
stateless: true
logout: true
anonymous: true
guard:
authenticators:
- 'token_authenticator'
login:
pattern: ^/api/login
stateless: true
anonymous: true
form_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
username_parameter: username
password_parameter: password
api:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
```
I'm on v2.4 /w SF 3.3#dev, and it seems that somewhere between the versions something crashed. Still, even after renewing the keys/regenerating a token, nothing is good for the moment and I've always this error.
I'm currently doing my requests through Postman, the Token is correctly generated and the problem is not coming from the Authorization param in the header, I've tried a lot of stuff on it to see if it was my fault or not, seems not in this case,
Any helps / tips on this is highly appreciated :)
You should regenerate your public and private keys using the following commands:
openssl genrsa -out config/jwt/private.pem -aes256 4096
openssl rsa -pubout -in config/jwt/private.pem -out config/jwt/public.pem
And make sure the passphrase is 'pass' for the configuration to work.
I'm building a symfony REST Api in which I'm trying to get HWIOAuthBundle, FOSUserBundle and LexikJWTBundle working all together.
I followed this gist for the HWIOAuthBundle/FOSUserBundle integration.
Now I'm getting the facebook login form when hitting the /login route. But after submition I get this error :
[2/2] HttpTransportException: Error while sending HTTP request
[1/2] RequestException: Failed to connect to graph.facebook.com port 443: Bad access
INFO - Matched route "hwi_oauth_service_redirect".
CRITICAL -
Uncaught PHP Exception HWI\Bundle\OAuthBundle\OAuth\Exception\HttpTransportException:
"Error while sending HTTP request"
at C:\myProject\vendor\hwi\oauth-bundle\OAuth\ResourceOwner\AbstractResourceOwner.php
line 257
DEBUG -
Notified event "kernel.request" to listener
"Symfony\Component\EventDispatcher\Debug\WrappedListener::__invoke".
...
I'm now looking for help about this. Or any other way to get those bundles to work together.
config.yml :
hwi_oauth:
# list of names of the firewalls in which this bundle is active, this setting MUST be set
firewall_names: [auth]
http_client:
timeout: 10000
verify_peer: false
max_redirects: 1000
ignore_errors: false
fosub:
username_iterations: 300
properties:
# these properties will be used/redefined later in the custom FOSUBUserProvider service.
facebook: facebook_id
# an optional setting to configure a query string parameter which can be used to redirect
# the user after authentication, e.g. /connect/facebook?_destination=/my/destination will
# redirect the user to /my/destination after facebook authenticates them. If this is not
# set then the user will be redirected to the original resource that they requested, or
# the base address if no resource was requested. This is similar to the behaviour of
# [target_path_parameter for form login](http://symfony.com/doc/2.0/cookbook/security/form_login.html).
# target_path_parameter: _destination
# an optional setting to use the HTTP REFERER header to be used in case no
# previous URL was stored in the session (i.e. no resource was requested).
# This is similar to the behaviour of
# [using the referring URL for form login](http://symfony.com/doc/2.0/cookbook/security/form_login.html#using-the-referring-url).
# use_referer: true
# here you will add one (or more) configurations for resource owners
resource_owners:
facebook:
type: facebook
client_id: {id}
client_secret: {secret}
scope: ""
infos_url: "https://graph.facebook.com/me?fields=name,email,picture.type(square)"
options:
display: popup
security.yml :
firewalls:
auth:
pattern: ^/api/minisite/user/auth
anonymous: true
stateless: true
form_login:
check_path: /api/minisite/user/auth/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
username_parameter: username
password_parameter: password
require_previous_session: false
oauth:
resource_owners:
facebook: "/api/minisite/user/auth/facebook/login/check-facebook"
login_path: /api/minisite/user/auth/facebook/login
check_path: /api/minisite/user/auth/login_check
failure_path: /api/minisite/user/auth/facebook/login
oauth_user_provider:
#this is my custom user provider, created from FOSUBUserProvider - will manage the
#automatic user registration on your site, with data from the provider (facebook. google, etc.)
service: my_user_provider
logout: true
anonymous: true
access_control:
- { path: ^/api/minisite/user/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/minisite, roles: IS_AUTHENTICATED_FULLY }
Configure this in your config.yml file.
hwi_oauth:
http_client:
verify_peer: false
Setting this allows you to turn off SSL verification.
I got the same problem using HWI on localhost. I don't know, but if it's your case, try to upload your work on a server. The reason of this issue is that your are using the port 80, but facebook need that you use the port 443 or use ipv6.
Hope this help
I am configuring Fosuserbundle and HWIOAuth Bundle to Login from Facebook and Google.
issue i am facing is:
When i try to login a user through google account , when he is not already logged in , as i enter credentials of Google and press login it shows me error
No route found for GET/
Or some times
No route found for GET/ ( from wwww.mysite.com/app_dev.php/en/home/ )
it does store information of user (e.g Email , user name etc) in databases , when i go to home page i find my self logged in.
When i try to log in a user who is already logged in with hi google account , it works perfectly.
I am stuck with this... Step by step followed This documentation. Everything is working perfectly except this.
You help would be appreciated.
config.yml
hwi_oauth:
#this is my custom user provider, created from FOSUBUserProvider - will manage the
#automatic user registration on your site, with data from the provider (facebook. google, etc.)
#and also, the connecting part (get the token and the user_id)
connect:
account_connector: my_user_provider
# name of the firewall in which this bundle is active, this setting MUST be set
firewall_name: main
fosub:
# username_iterations: 30
properties:
# these properties will be used/redefined later in the custom FOSUBUserProvider service.
facebook: facebook_id
google: google_id
resource_owners:
facebook:
type: facebook
client_id: "xxxxxxxxxxxxxxxxxxxxxxx"
client_secret: "xxxxxxxxxxxxxxxxxxxxxxx"
scope: ""
google:
type: google
client_id: "xxxxxxxxxxxxxxxxxxxxxxx"
client_secret: "xxxxxxxxxxxxxxxxxxxxxxx"
scope: "https://www.googleapis.com/auth/userinfo.email
--------------------security.yml------------
firewalls:
main:
pattern: ^/
form_login:
check_path: /login_check
login_path: /login
provider: fos_userbundle
# always_use_default_target_path: true
# default_target_path: /%locale%/home
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
login_path: /login
failure_path: /login
oauth_user_provider:
#this is my custom user provider, created from FOSUBUserProvider - will manage the
#automatic user registration on your site, with data from the provider (facebook. google, etc.)
service: my_user_provider
logout:
path: /logout
target: /%locale%/home
anonymous: ~
-----------------routing.yml------------
fos_user_security:
resource: "#FOSUserBundle/Resources/config/routing/security.xml"
fos_user_profile:
resource: "#FOSUserBundle/Resources/config/routing/profile.xml"
prefix: /profile
fos_user_register:
resource: "#FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /register
fos_user_resetting:
resource: "#FOSUserBundle/Resources/config/routing/resetting.xml"
prefix: /resetting
fos_user_change_password:
resource: "#FOSUserBundle/Resources/config/routing/change_password.xml"
prefix: /profile
#HWIOAuthBundle routes
hwi_oauth_security:
resource: "#HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /login
hwi_oauth_connect:
resource: "#HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /login
hwi_oauth_redirect:
resource: "#HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /login
facebook_login:
pattern: /login/check-facebook
google_login:
pattern: /login/check-google
I'm using a custom authenticator that implements SimpleFormAuthenticationInterface.
However, because of the way forms have their input name="form[username]" I'm not able to pass that to the username_parameter and into createToken. Is there a way to do this or will I have to write my own Authentication Listener?
Here's my config:
firewalls:
secured_area:
provider: UserRepository
pattern: ^/user
simple_form:
username_parameter:
password_parameter:
authenticator: UserAuthenticator
login_path: /login
check_path: /user/auth
Apparently Request's Symfony\Component\HttpFoundation\ParameterBag resolves parameters that are of html array form in the security.yml configuration
Under:
https://github.com/symfony/symfony/blob/2.4/src/Symfony/Component/HttpFoundation/ParameterBag.php#L103-L150
So you can use and do something like:
firewalls:
secured_area:
provider: UserRepository
pattern: ^/user
simple_form:
username_parameter: MyForm[username]
password_parameter: MyForm[password]
authenticator: UserAuthenticator
login_path: /login
check_path: /user/auth