Skip to content
This repository has been archived by the owner on May 17, 2021. It is now read-only.

Provide full examples for config when integrated with FOS? #10

Closed
tcowin opened this issue Aug 6, 2012 · 8 comments
Closed

Provide full examples for config when integrated with FOS? #10

tcowin opened this issue Aug 6, 2012 · 8 comments

Comments

@tcowin
Copy link

tcowin commented Aug 6, 2012

I'm trying to configure this with FOSUserBundle, and it would be helpful if you had complete examples for app/config/security.yml, config.yml and the User class as it would be with FR3D and FOS fully integrated... (especially in firewalls)

@Maks3w
Copy link
Owner

Maks3w commented Aug 24, 2012

This is the security.yml that I use with the 2.0.x branch

security:
    access_decision_manager:
        # Strategy can be: affirmative, unanimous or consensus
        strategy: unanimous # Vote the user if don't have all roles required.

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        chain_provider:
            providers: [fos_userbundle, fr3d_ldapbundle]

        fr3d_ldapbundle:
            id: fr3d_ldap.security.user.provider

        fos_userbundle:
            id: fos_user.user_manager

    firewalls:
        main:
            pattern: ^/
            fr3d_ldap: ~
            form_login:
                provider: chain_provider
#                always_use_default_target_path: true
#                default_target_path: /profile
            logout:       true
            anonymous:    true
            remember_me:
                key:      %secret%
                path:     /
                domain:   ~ # Defaults to the current domain from $_SERVER
                secure:   true
                httponly: true

    access_control:
        - { path: ^/$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/profile/, role: IS_AUTHENTICATED_REMEMBERED, requires_channel: https }
        - { path: ^/locker/, role: IS_AUTHENTICATED_REMEMBERED, requires_channel: https }
        - { path: ^/admin/user/, role: [ROLE_SUPER_ADMIN, IS_AUTHENTICATED_FULLY], requires_channel: https }
        - { path: ^/admin, role: [ROLE_ADMIN, IS_AUTHENTICATED_FULLY], requires_channel: https }

    factories:
        - "%kernel.root_dir%/../vendor/bundles/FR3D/LdapBundle/Resources/config/security_factories.xml"

@Maks3w Maks3w closed this as completed Sep 15, 2012
@DRAKUN
Copy link

DRAKUN commented Sep 20, 2012

Hi

Maks3w you have clove this discusion without finish please help us for this
I'm trying to configure this with FOSUserBundle, and it would be helpful if you had complete examples for app/config/security.yml, config.yml and the User class as it would be with FR3D and FOS fully integrated... (especially in firewalls)

@tcowin
Copy link
Author

tcowin commented Sep 21, 2012

@DRAKUN - the security.yml is above, and it looks pretty similar to mine. Each application and environment are pretty unique, so it does appear to take some trial and error to find the config that will be just right for you. The relevant parts of my config.yml look like this(I'm authenticating against Windows Server 2003):

fos_user:
    db_driver: orm
    firewall_name: admin
    user_class: Acme\SecurityBundle\Entity\User

sonata_user:
    security_acl: true

fr3d_ldap:
    client:
        host:         <ip address of your LDAP (Windows AD?) Server>
#        port:         389    # Optional
        version:        3    # I think this is specific to Windows AD - possibly 2003
        username:     ldapproxyuser@yourADdomain    # Windows requires you to authenticate to be able to query
        password:     whatever    # Optional
        optReferrals: 0  #  I think this is specific to Windows AD - possibly 2003
#        useSsl:       true   # Enable SSL negotiation. Optional
#        useStartTls:  true   # Enable TLS negotiation. Optional
    user:
        baseDn: cn=users, dc=yourADdomain, dc=local
#        baseDn: ou=users 
        filter: (&(ObjectClass=Person))
        attributes:          # Specify ldap attributes mapping [ldap attribute, user object method]
#           - { ldap_attr: uid,  user_method: setUsername } # Default
#           - { ldap_attr: sAMAccountName,   user_method: setName }     # Optional
           - { ldap_attr: samaccountname,   user_method: setUsername }     # I found that these needed to be lowercase
           - { ldap_attr: proxyaddresses, user_method: setEmailFromAD }     # to pick up email addresses...read on
#           - { ldap_attr: ...,  user_method: ... }         # Optional
#   service:
#       user_manager: fos_user.user_manager          # Overrides default user manager
#       ldap_manager: fr3d_ldap.ldap_manager.default # Overrides default ldap manager

If you're not sure that you're getting a tight connection to your AD server, download and tweak this script:
http://ubuntuforums.org/showthread.php?t=1926478
until you're confident what parameters your AD server is happy with. I found this quite helpful.

You will need to create your own "class User extends BaseUser implements LdapUserInterface".

Mine looks like this:

namespace Acme\SecurityBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FR3D\LdapBundle\Model\LdapUserInterface;
use FOS\UserBundle\Entity\User as BaseUser;

/**
 * Acme\SecurityBundle\Entity\User
 *
 * @ORM\Table(name="fos_user_user")
 * @ORM\Entity(repositoryClass="Acme\SecurityBundle\Entity\UserRepository")
 */
class User extends BaseUser implements LdapUserInterface
{
  /**
   * Ldap Object Distinguished Name
   * @var string $dn
   */
  protected $dn;

  /**
   * @var integer $id
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  protected $id;


    /**
     * @var datetime $createdAt
     *
     * @ORM\Column(name="created_at", type="datetime", nullable=false)
     */
    private $createdAt;

    /**
     * @var datetime $updatedAt
     *
     * @ORM\Column(name="updated_at", type="datetime", nullable=false)
     */
    private $updatedAt;

  public function __construct()
  {
    parent::__construct();
  }

  /**
   * Get id
   *
   * @return integer
   */
  public function getId()
  {
      return $this->id;
  }

  /**
   * {@inheritDoc}
   */
  public function setDn($dn)
  {
    $this->dn = $dn;
  }

  /**
   * {@inheritDoc}
   */
  public function getDn()
  {
    return $this->dn;
  }

    /**
     * Sets the email.
     *
     * @param string $email
     * @return User
     */
    public function setEmailFromAD($email)
    {
        return parent::setEmail(preg_replace("/smtp:/i", "", $email));
    }

    /**
     * Set createdAt
     *
     * @param datetime $createdAt
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;
    }

    /**
     * Get createdAt
     *
     * @return datetime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param datetime $updatedAt
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;
    }

    /**
     * Get updatedAt
     *
     * @return datetime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
}

I also introduced some hacks to vendor/bundles/FR3D/LdapBundle/Ldap/LdapManager.php (I know - I should have extended it I guess :) ruhroh!) I don't have a diff here, but I think the only changes I made were in hydrate():

    protected function hydrate(LdapUserInterface $user, array $entry)
    {
        $user->setPassword('');

        if ($user instanceof AdvancedUserInterface) {
            $user->setEnabled(true);
        }
/*
Array ( [samaccountname] => Array ( [count] => 1 [0] => TomCowin ) [0] => samaccountname [count] => 1 [dn] => CN=Tom Cowin,CN=Users,DC=yourADDomain,DC=local )

Array ( [proxyaddresses] => Array ( [count] => 1 [0] => SMTP:Tom.Cowin@Acme.com ) [0] => proxyaddresses [samaccountname] => Array ( [count] => 1 [0] => TomCowin ) [1] => samaccountname [count] => 2 [dn] => CN=Tom Cowin,CN=Users,DC=yourADDomain,DC=local ) 
*/
        foreach ($this->params['attributes'] as $attr) {
            $ldapValue = $entry[$attr['ldap_attr']];
            $value = null;

            if ((array_key_exists('count', $ldapValue) &&  $ldapValue['count'] == 1)
                    || !array_key_exists('count', $ldapValue)) {

                $value = $ldapValue[0];
            } else {
                $value = array_slice($ldapValue, 1);
            }

            call_user_func(array($user, $attr['user_method']), $value);
        }

        $user->setDn($entry['dn']);
        $user->addRole('ROLE_ADMIN');
        $today = new \DateTime();

        // When
        $user->setCreatedAt($today);
        $user->setUpdatedAt($today);
    }

@DRAKUN
Copy link

DRAKUN commented Sep 21, 2012

Ah it is too cool, months when I have a hard time on it you is saved me thank you openly(frankly) thank you for the bottom of the heart

Now can you sent by e-mails to user AD on 2003 through tone applications on symfony.
( Example I want that during a validation of form an e-mail is sent to user)

If yes I would like to know by where you passed.
Thank you

@Maks3w
Copy link
Owner

Maks3w commented Sep 21, 2012

@DRAKUN Your request is out of the scope of FR3DLdapBundle. Maybe at Symfony Forums you can get more luck.

@Maks3w Maks3w reopened this Sep 21, 2012
@Maks3w Maks3w closed this as completed Sep 21, 2012
@frjaraur
Copy link

Hi all,
I think is better to use 'mail' LDAP attribute instead of 'proxyaddresses'... It returns an array and throught me an exception with canonalizer (email).

Thanks For this Bundle!!!

@njbarrett
Copy link

FYI to get this method to work I also had to set

        accountDomainName: <FQDN> e.g example.com
        accountDomainNameShort: example

@hugo-aam
Copy link

Hi @Maks3w,
Can you confirm me this last bundle release is compatible with a 2.7.7 version of symfony ?
If not, which versions are compatible ?

Thanks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants