symfonyauthenticationldapfosuserbundlefr3dldapbundle

Override FR3DLdapBundle functionality and controllers


I've installed and configured FR3DBundle with FOSUserBundle and everything works OK , but there is something that I do not understand, why FR3DLdpaBundle save users in the database without password ? when I'm trying to Login the second time, two situations come to me : if the order of the chain providers is :

providers: [fr3d_ldapbundle,fos_userbundle ] :

FR3DLdapBundle trying to insert the same user another time in the database (duplicated entry) !

when the order of the chain providers is :

providers: [fos_userbundle,fr3d_ldapbundle ] : 

the error invalid credential appear to me cause in the first login the user saved without password in the database. So I'm asking is there any way to hack the Bundle and override some controllers and functionality to get login functionality work successfully?

Here is My Config.yml file :

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }
    - { resource: "@EvalBundle/Resources/config/services.yml" }

# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: en

assetic:
    debug:          '%kernel.debug%'
    use_controller: '%kernel.debug%'
    filters:
        cssrewrite: ~

framework:
    #esi: ~
    #translator: { fallbacks: ['%locale%'] }
    secret: '%secret%'
    router:
        resource: '%kernel.root_dir%/config/routing.yml'
        strict_requirements: ~
    form: ~
    csrf_protection: ~
    validation: { enable_annotations: true }
    #serializer: { enable_annotations: true }
    templating:
        engines: ['twig']
    default_locale: '%locale%'
    trusted_hosts: ~
    trusted_proxies: ~
    session:
        # http://symfony.com/doc/current/reference/configuration/framework.html#handler-id
        handler_id:  session.handler.native_file
        save_path:   "%kernel.root_dir%/../var/sessions/%kernel.environment%"
    fragments: ~
    http_method_override: true
    assets: ~
    php_errors:
        log: true
    translator: ~

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
    cache:  false
    form_themes :
        - bootstrap_3_layout.html.twig
        - bootstrap_3_horizontal_layout.html.twig

# Doctrine Configuration
doctrine:
    dbal:
        driver: pdo_mysql
        host: '%database_host%'
        port: '%database_port%'
        dbname: '%database_name%'
        user: '%database_user%'
        password: '%database_password%'
        charset: UTF8
        mapping_types:
            enum: string


        # if using pdo_sqlite as your database driver:
        #   1. add the path in parameters.yml
        #     e.g. database_path: "%kernel.root_dir%/../var/data/data.sqlite"
        #   2. Uncomment database_path in parameters.yml.dist
        #   3. Uncomment next line:
        #path: '%database_path%'

    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true

# Swiftmailer Configuration
swiftmailer:
    transport: '%mailer_transport%'
    host: '%mailer_host%'
    username: '%mailer_user%'
    password: '%mailer_password%'
    spool: { type: memory }

fos_user:
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: main
    user_class: EvalBundle\Entity\Collaborator
    from_email:
        address: sahnoun.mabrouk@gmail.com
        sender_name: sahnoun MABROUK
fr3d_ldap:
    driver:
        host: 172.16.20.21
        port: 389    # Optional
        username: cn=Administrator, cn=Users, dc=uib, dc=dev    # Optional
        password: Pr0xym-1T    # Optional
#       allowEmptyPassword:  true # Optional
#       bindRequiresDn:      true   # Optional
#       baseDn:   dc=uib, dc=dev   # Optional
#       accountFilterFormat: (&(uid=%s)) # Optional. sprintf format %s will be the username
#       optReferrals:        false  # Optional
#       useSsl:              true   # Enable SSL negotiation. Optional
#       useStartTls:         true   # Enable TLS negotiation. Optional
#       accountCanonicalForm: 3 # ACCTNAME_FORM_BACKSLASH this is only needed if your users have to login with something like HOST\User
#       accountDomainName: HOST
#       accountDomainNameShort: HOST # if you use the Backslash form set both to Hostname than the Username will be converted to HOST\User
    user:
        baseDn: cn=Users, dc=uib, dc=dev
        usernameAttribute: sAMAccountName # Optional

        filter: (&(ObjectClass=Person))
        attributes:          # Specify ldap attributes mapping [ldap attribute, user object method]
        - { ldap_attr: samaccountname,  user_method: setUsername }
        - { ldap_attr: samaccountname,  user_method: setUsernameCanonical }
        - { ldap_attr: userprincipalname,  user_method: setEmail }
        - { ldap_attr: userprincipalname,  user_method: setEmailCanonical }

        #- { ldap_attr: mail,  user_method: setmail }
        #- { ldap_attr: cn,  user_method: setgivenName } # Default
        #- { ldap_attr: cn,   user_method: setName }     # Optional

    #           - { ldap_attr: ...,  user_method: ... }         # Optional
    service:
        user_hydrator: fr3d_ldap.user_hydrator.default # Overrides default user hydrator
        ldap_manager: fr3d_ldap.ldap_manager.default   # Overrides default ldap manager
        ldap_driver: fr3d_ldap.ldap_driver.zend        # Overrides default ldap driver
easy_admin:
    entities:
        - EvalBundle\Entity\Family
        - EvalBundle\Entity\Profession


knp_paginator:
    page_range: 1                      # default page range used in pagination control
    default_options:
        page_name: page                # page query parameter name
        sort_field_name: sort          # sort field query parameter name
        sort_direction_name: direction # sort direction query parameter name
        distinct: true                 # ensure distinct results, useful when ORM queries are using GROUP BY statements
    template:
        pagination: 'KnpPaginatorBundle:Pagination:twitter_bootstrap_v3_pagination.html.twig'     # sliding pagination controls template
        sortable: 'KnpPaginatorBundle:Pagination:sortable_link.html.twig' # sort link template

My security.yml :

# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
    erase_credentials: false
    encoders:
            FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
            ROLE_ADMIN:       ROLE_ADMIN
            ROLE_SUPER_ADMIN: ROLE_SUPER_ADMIN
    providers:
            chain_provider:
                    chain:
                            providers: [fos_userbundle,fr3d_ldapbundle]

            fr3d_ldapbundle:
                        id: fr3d_ldap.security.user.provider

            fos_userbundle:
                        id: fos_user.user_provider.username

    firewalls:
        api:
              pattern:    ^/api
              fr3d_ldap_httpbasic: ~
        main:
          pattern:    ^/
          fr3d_ldap:  ~
          form_login:
              always_use_default_target_path: true
              default_target_path: /
          logout:
              path: /logout
              target:  /login
          anonymous:  true
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

    providers:
            fr3d_ldapbundle:
              id: fr3d_ldap.security.user.provider

    encoders:
          AcmeBundle\Acme\User\LdapUser: plaintext

    access_control:
            - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/admin*, role: ROLE_SUPER_ADMIN}

Solution

  • Take a look at my article on using Symfony and the FR3DLdapBundle and together with AD here:

    https://alvinbunk.wordpress.com/2016/03/25/symfony-ad-integration/

    It might help you. Using the providers like so:

    providers: [fos_userbundle,fr3d_ldapbundle]
    

    Is the correct way to configure; if the user already exists in the fos_user table, and you are getting errors about duplicated entries, you might have to delete the existing entry. Maybe you configured incorrectly at first.

    Also, the passwords are not stored in either the fos_user table, or anywhere else, except in the LDAP server. You just "authenticate" the user against LDAP.