JWTRefreshTokenBundle change user_identity_field Symfony 5.4 + ApiPlatform - symfony

I am using : Symfony 5.4 + ApiPlatform + JWTRefreshTokenBundle 1.1
JWTRefreshTokenBundle => https://github.com/markitosgv/JWTRefreshTokenBundle
I need to change this parameter "user_identity_field" but there is no way to change this :
I tried to change the Yaml =>
gesdinet_jwt_refresh_token:
user_identity_field: email
user_provider: app_user_provider
I tried to modify this function in my user provider (app_user_provider) entity User.php :
public function getUserIdentifier(): string
{
return (string) $this->id;
}
Right now the better I can get is to have the ID instead of the E-mail in the user name column in my database, but as soon as I try to refresh the token, I get this message => " 401 "Invalid credentials".
I am tried to have "ID" instead of "E-MAIL" as user_identity_field.
Has anyone found a solution ?
Thanks.

Sf 5,4+
#gesdinet_jwt_refresh_token.yaml
gesdinet_jwt_refresh_token:
user_identity_field: email
ttl: 2592000
firewall: login
user_provider: security.user.provider.concrete.app_user_provider

i think you need to change the app_user_provider in the security.yaml file :
app_user_provider:
entity:
class: App\Entity\User
property: id
jwt:
lexik_jwt:
class: App\Entity\User
i think the problem is : symfony try to authneticate user with the app_user_provider and you have a conflict because id's are in your JWT but framework search for email.
For verify that you can check your tokens on : https://jwt.io/

The JWTRefreshTokenBundle (gesdinet/jwt-refresh-token-bundle) is build upon the JWTAuthenticationBundle (lexik/jwt-authentication-bundle), which is the bundle that defines the user_identity_field configuration:
# config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
user_identity_field: 'email'

Related

Symfony 5 LDAP JumpCloud Authentication

I am just trying to configure LDAP authentication using JumpCloud service.
JumpCloud is public LDAP server with web adminisration. For connectiong to LDAP I am using built-in modul and following this tutorial: http://symfony.com/doc/current/security/ldap.html
It seems the system will connect succesly on to LDAP but cannot authenticate users.
Output header:
Output header
Here are my settings:
config/services.yaml
Symfony\Component\Ldap\Ldap:
arguments: ['#Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
arguments:
- host: ldap.jumpcloud.com
port: 636
encryption: ssl
options:
protocol_version: 3
referrals: false
config/packages/security.yaml
providers:
my_ldap:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com
default_roles: ROLE_USER
uid_key: uid
extra_fields: ['mail']
filter: ({uid_key}={username})
firewalls:
main:
anonymous: false
http_basic_ldap:
service: Symfony\Component\Ldap\Ldap
dn_string: 'uid=LDAP_ADMIN_USERNAME,ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com'
search_password: 'LDAP_ADMIN_PASS'
Manual connection test:
$dn = "uid=LDAP_ADMIN_USERNAME,ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com";
$password = "LDAP_ADMIN_PASS";
$ldap = Ldap::create('ext_ldap', ['connection_string' => 'ldaps://ldap.jumpcloud.com:636']);
$ldap->bind($dn, $password);
$query = $ldap->query('ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com', '(objectClass=inetOrgPerson)');
$results = $query->execute();
This code have returned valid output:
array (size=3)
0 => object(Symfony\Component\Ldap\Entry)[5504]
private 'dn' => string 'uid=janakdom,ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com' (length=68)
private 'attributes' => ..
1 => object(Symfony\Component\Ldap\Entry)[5093]
private 'dn' => string 'uid=ldapservice,ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com' (length=71)
private 'attributes' => ...
2 => object(Symfony\Component\Ldap\Entry)[4926]
private 'dn' => string 'uid=test,ou=Users,o=MY_ORG_ID,dc=jumpcloud,dc=com' (length=64)
private 'attributes' => ...
A absolutely don't know where the problem could be. I tried everything what occurred to me. I also use oficial JumpCloud documentation
I would ask you for help.
Thank you very much
DJ
Full disclosure, I work for JumpCloud, in support for the last couple years, and in a technical editor capacity now. A couple of changes to your configuration may help:
1) Under "providers > my_ldap > ldap:", there is no "search_dn", which will need to be the service LDAP Bind DN created in JumpCloud and appears to have been configured under "security > firewalls > main > http_basic_ldap:" per the screenshot above as 'uid=LDAP_ADMIN_USERNAME,ou=users,o=,dc=jumpcloud,dc=com'.
2) Under "security > firewalls > main > http_basic_ldap:", the "dn_string" is used to construct the FUll LDAP Bind DN of the user being authenticated. Per the example in the documentation, this needs to be set with the proper syntax for value substitution as noted below.
'uid={username},ou=users,o=,dc=jumpcloud,dc=com'
Hope this helps -- if not, I would definitely suggest opening a case with support#jumpcloud.com.
Brandon

syntax for token_provider in symfony remember_me

I'm building remember_me functionality in symfony. Instead of tokens being stored in cookies I want to store them in database So, I'm trying to use an option called token_provider but there is not much information detailed on Symfony.com.
I am new to Symfony, can any one share the syntax of "token_provider" in security.yml->firewalls->remember_me?
any help will be appreciated.
Changes I have done
Created a custom service which extends Symfony\Bridge\Doctrine\Security\RememberMe\DoctrineTokenProvider and passed the db connection object from the constructor
class CustomTokenService extends DoctrineTokenService
{
public function __construct(EntityManagerInterface $em){
parent::__construct($em->getConnection());
}
}
Registered this service in app/config/services.yml
custom service in services.yml:
token_service:
alias:{App}\Bundle\Services\Utilities\CustomTokenService
public: true
In Security.yml:
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /
domain: ~
remember_me_parameter: _stay_signedin
token_provider: token_service

Symfony CSRF check failing

Getting:
"The CSRF token is invalid. Please try to resubmit the form."
Controller:
$message = new Message();
$form = $this->createForm(new MessageType($locales), $message);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
...
// never reached
}
}
Inspecting the raw POST data, it does include a _token field:
message[title]: Test
message[subtitle]:
message[_token]:0LpwU3llG-FhyEc0o12b7rU0Pg2zSAb7xpUwAF1Xw3g
So it's not the issue lots are having missing {{ form_rest(form) }}
Have you read this from the docs (http://symfony.com/doc/current/cookbook/security/csrf_in_login_form.html)?
First, configure the Security component so it can use CSRF protection. The Security component needs a CSRF token provider. You can set this to use the default provider available in the Security component
# app/config/security.yml
security:
# ...
firewalls:
secured_area:
# ...
form_login:
# ...
csrf_token_generator: security.csrf.token_manager
I think maybe you need to specify which token manager to use for the _token

FR3DLdapBundle Login with email

I'm new on LDAP concept and i have to make a integration with LDAP and FosUserBundle.
I've installed both bundles, fosuser and FR3DLdapBundle, fosuser is working but i'm missing something about LDAP login.
I need to login with email.
I have the following config: http://pastebin.com/USkJqtbD
I'm using this website for tests: http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
I'm using email: riemann#ldap.forumsys.com and password: password
But i have the following error
[2015-05-18 16:36:58] ldap_driver.DEBUG: ldap_search(cn=read-only-admin,dc=example,dc=com, (&(objectClass=*)(uid=riemann#ldap.forumsys.com)), uid,mail) [] []
[2015-05-18 16:36:58] security.INFO: User riemann#ldap.forumsys.com not found on ldap [] []
Thank you in advance for you help
With the FR3D Ldap bundle the first attribute that you add in the attributes list is then one that it uses to search by.
In your config the first attribute is uid, so I would suspect that if you used the uid as the username then it would properly. To sort it you will just need to switch up the order so the your mail attribute is first in the list.
fr3d_ldap:
// ...
user:
// ...
attributes: # Specify ldap attributes mapping [ldap attribute, user object method]
- { ldap_attr: mail, user_method: setEmail } # Default
- { ldap_attr: uid, user_method: setUsername }
You have to adapt the search query for find by email.
https://github.com/Maks3w/FR3DLdapBundle/blob/master/Resources/doc/index.md#4-configure-configyml
# app/config/config.yml
fr3d_ldap:
driver:
accountFilterFormat: (&(email=%s)) # Optional. sprintf format %s will be the username

symfony2 login by username or email

I'm using the standard authentication mechanism of Symfony2 and I want to let the user use either his username or email to login, but I can't find out why it's not working. I've tested the repository class and it works as expected. I've followed this how-to.
Here's my user provider class:
<?php
namespace My\UserBundle\Entity;
use Doctrine\ORM\EntityRepository ,
Symfony\Component\Security\Core\User\UserProviderInterface ,
Symfony\Component\Security\Core\User\UserInterface;
/**
* UserRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class UserRepository extends EntityRepository implements UserProviderInterface
{
function loadUserByUsername($username)
{
$qb = $this->createQueryBuilder('u') ;
return
$qb->select('u')
->where(
$qb->expr()->orx(
$qb->expr()->like('u.username' ,':username') ,
$qb->expr()->like('u.email' ,':username')
)
)
//->andWhere($qb->expr()->eq('u.enabled' ,'true') )
->setParameters(array('username' =>$username ) )
->getQuery()
->getResult() ;
}
function refreshUser(UserInterface $user)
{
return $this->loadUserByUsername($user->getUsername() );
}
function supportsClass($class)
{
return $class === 'My\UserBundle\Entity\User';
}
}
I propose a more simple approach that only requires to edit security.yml file.
You must to create two diferent security providers but both using the same User class. The first has username as property and the second has email as property.
Then you create a chain_provider that includes the two providers and use it in your firewall section
security:
providers:
chain_provider:
chain:
providers: [db_username, db_email]
db_username:
entity:
class: MyUserBundle:User
property: username
db_email:
entity:
class: MyUserBundle:User
property: email
firewalls:
default:
anonymous: ~
provider: chain_provider
form_login:
login_path: /login
check_path: /login
I don't know if this approach is a clean practice, but is fast, simple and it works ok.
well guys the thing is in my security.yml i had this
providers:
main:
entity: { class: My\UserBundle\Entity\User ,property : username}
so i had to take off that parameter property :username
Taking off the property: username lets the UserProviderInterface load the user as expected when it logs in, but does not call the refreshUser() method as expected. I put in checks to see if it gets called but it doesn't.
The class that reloads the user on each access is ContextListener::refreshUser(TokenInterface $token) method. In this the interface iterates through the UserProviders and calls the refreshUser that first returns a non-null user.
I could make sure of this because, in the original load, I combine all different entities to make one SQL call instead of 7. And when the user reloads, it calls 7 times.
Also the method EntityUserProvider::refreshUser() doesn't call the repository's method and instead reloads from the database directly.
Your provider class is correct, and you are correct that the problem is in security.yml, however, your solution is incorrect.
According to the documentation, your security.yml file should look like this:
security:
# ...
providers:
administrators:
entity: { class: MyUserBundle:User }
Notice that the class is defined as the Bundle, not the direct class.
The way you have your code right now, symfony is completly ignoring your repository class until you define your security.yml correctly. And as #Anand pointed out, just removing the property does not invoke refreshUser. However, it looks like if you are using your own Repository, you do not need to define the property (since it's being defined in your query).

Resources