Symfony2中的saml2身份提供程序

Symfony2中的saml2身份提供程序,symfony,saml,simplesamlphp,Symfony,Saml,Simplesamlphp,我必须实现SAML2身份提供程序(IdP)并将其与现有的Symfony 2应用程序集成 我发现了一些实现服务提供者(SP)而不是身份提供者的捆绑包,所以我想我可以使用。还有其他解决办法吗 如何将用户提供程序逻辑与SimpleSAMLphp集成?我发现: 这是您找到的库的简单symfony2包装 更多的使用和良好的记录 看看这两个。第一个非常简单,我不知道是否有足够的文档,当然是一个活跃的项目。第二种方法似乎更强大、更有文档记录,但配置起来可能更困难 希望此帮助更新 正如米洛斯·托米奇在评论中提到

我必须实现SAML2身份提供程序(IdP)并将其与现有的Symfony 2应用程序集成

我发现了一些实现服务提供者(SP)而不是身份提供者的捆绑包,所以我想我可以使用。还有其他解决办法吗

如何将用户提供程序逻辑与SimpleSAMLphp集成?

我发现:

  • 这是您找到的库的简单symfony2包装
  • 更多的使用和良好的记录 看看这两个。第一个非常简单,我不知道是否有足够的文档,当然是一个活跃的项目。第二种方法似乎更强大、更有文档记录,但配置起来可能更困难


    希望此帮助更新

    正如米洛斯·托米奇在评论中提到的那样,aerialship/lightsaml被替换为。你可以找到一个

    +++++++++++++++++++++++++++

    我最近建立了一个SAML解决方案,使用as IDP和as SP,一切正常

    我建议先安装Simplesamlphp,然后再安装

    一旦IDP启动并运行,您应该会看到一个欢迎页面和一个名为Federation的选项卡(或者类似的,我的安装是德语的)。在这里,您应该看到一个选项“SAML2.0IDP元数据”。按照该链接将显示的XML复制到一个单独的文件并保存该文件

    在symfony方面,我创建了一个新的Bundle并称之为“SamlBundle”。下载并安装SamlSPBundle,如其文档中所述(步骤1和步骤2)

    创建SSO状态/用户类(步骤3)。以下是我如何做到这一点的示例:

    namespace SamlBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Security\Core\User\UserInterface;
    
    /**
     * @ORM\Entity
     * @ORM\Table(name="samlUser")
     */
    class SamlUser extends \AerialShip\SamlSPBundle\Entity\SSOStateEntity implements UserInterface
    {
    
    /**
     * initialize User object and generates salt for password
     */
    public function __construct()
    {
        if (!$this->userData instanceof UserData) {
            $this->userData  = new UserData();
        }
        $this->setRoles('ROLE_USER');
    }
    
    /**
     * @var int
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    
    /**
     * @var string username
     *
     * @ORM\Column(type="string", length=64, nullable=true)
     */
    protected $username;
    
    /**
     * @var string targetedId
     *
     * @ORM\Column(type="string", length=64, nullable=true, name="targeted_id")
     */
    protected $targetedID;
    
    /**
     * @var string
     * @ORM\Column(type="string", length=32, name="provider_id", nullable=true)
     */
    protected $providerID;
    
    /**
     * @var string
     * @ORM\Column(type="string", length=32, name="auth_svc_name")
     */
    protected $authenticationServiceName;
    
    /**
     * @var string
     * @ORM\Column(type="string", length=64, name="session_index", nullable=true)
     */
    protected $sessionIndex;
    
    /**
     * @var string
     * @ORM\Column(type="string", length=64, name="name_id")
     */
    protected $nameID;
    
    /**
     * @var string
     * @ORM\Column(type="string", length=64, name="name_id_format")
     */
    protected $nameIDFormat;
    
    /**
     * @var \DateTime
     * @ORM\Column(type="datetime", name="created_on")
     */
    protected $createdOn;
    
    /**
     * @var UserData
     * @ORM\OneToOne(targetEntity="UserData", cascade={"all"}, fetch="EAGER")
     * @ORM\JoinColumn(name="user_data", referencedColumnName="id")
     */
    protected $userData;
    
    将类添加到config.yml(步骤4):

    更新security.yml(步骤5)。榜样

    providers:
        saml_user_provider:
            id: SamlToState
    
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
    
        saml:
            pattern: ^/(?!login_check)
            anonymous: true
            aerial_ship_saml_sp:
                login_path: /saml/sp/login
                check_path: /saml/sp/acs
                logout_path: /saml/sp/logout
                failure_path: /saml/sp/failure
                metadata_path: /saml/sp/FederationMetadata.xml
                discovery_path: /saml/sp/discovery
                local_logout_path: /logout
                provider: saml_user_provider
                create_user_if_not_exists: true
                services:
                    openidp:
                        idp:
                            #the XML-File you saved from the IDP earlier
                            file: "@SamlBundle/Resources/idp-FederationMetadata.xml"
                        sp:
                            config:
                                # required, has to match entity id from IDP XML
                                entity_id: http://your-idp-domain.com
                                # if different then url being used in request
                                # used for construction of assertion consumer and logout urls in SP entity descriptor
                                base_url: http://your-sp-domain.com
                            signing:
                                 #self signed certificate, see [SamlSPBundle docs][4]
                                cert_file: "@SamlBundle/Resources/saml.crt"
                                key_file: "@SamlBundle/Resources/saml.pem"
                                key_pass: ""
                            meta:
                                # must implement SpMetaProviderInterface
                                # id: my.sp.provider.service.id
    
                                # or use builtin SpMetaConfigProvider
                                # any valid saml name id format or shortcuts: persistent or transient
                                name_id_format: transient
                                binding:
                                    # any saml binding or shortcuts: post or redirect
                                    authn_request: redirect
                                    logout_request: redirect
            logout:
                path:   /logout
                target: /
                invalidate_session: true
    
    接下来,按照步骤6中所述导入路由。在继续执行步骤7之前,我建议首先创建用户提供程序类。以下是一个例子:

    namespace SamlBundle\Models;
    使用SamlBundle\Entity\SamlUser;
    使用Symfony\Component\DependencyInjection\ContainerInterface;
    使用Symfony\Component\Security\Core\User\UserInterface;
    使用AerialShip\SamlSPBundle\Bridge\SamlSpInfo;
    使用AerialShip\SamlSPBundle\Security\Core\User\UserManagerInterface作为UserManagerInterface;
    类SamlToState实现UserManagerInterface
    {
    /**
    *@var container接口基本捆绑包容器
    */
    公共集装箱;
    /**
    *具有DependencyInjection参数的构造函数。
    *
    *@param\Symfony\Component\DependencyInjection\ContainerInterface$container
    */
    公共函数构造(ContainerInterface$container){
    $this->container=$container;
    }
    /**
    *{@inheritardoc}
    */
    公共函数loadUserBySamlInfo(SamlSpInfo$samlInfo)
    {
    $user=$this->loadUserByTargetedID($samlInfo->getAttributes()['eduPersonTargetedID']->getFirstValue());
    返回$user;
    }
    私有函数loadUserByTargetedID($targetedID){
    $repository=$this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');
    $user=$repository->findOneBy(
    数组('targetedID'=>$targetedID)
    );
    如果($user){
    返回$user;
    }
    抛出new\Symfony\Component\Security\Core\Exception\UsernameNotFoundException();
    }
    /**
    *{@inheritardoc}
    */
    公共函数createUserFromSamlInfo(SamlSpInfo$samlInfo)
    {
    $repository=$this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');
    $user=$repository->findOneBy(
    数组('nameID'=>$samlInfo->getNameID()->getValue())
    );
    如果($user){
    $user->setUsername($samlInfo->getAttributes()['eduPersonPrincipalName']->getFirstValue());
    $user->setTargetedID($samlInfo->getAttributes()['eduPersonTargetedID']->getFirstValue());
    $user->setRoles($samlInfo->getAttributes()['role']->getFirstValue());
    }否则{
    $user=new SamlUser();
    $user->setUsername($samlInfo->getAttributes()['eduPersonPrincipalName']->getFirstValue());
    $user->setTargetedID($samlInfo->getAttributes()['eduPersonTargetedID']->getFirstValue());
    $user->setRoles($samlInfo->getAttributes()['role']->getFirstValue());
    $user->setSessionIndex($samlInfo->getAuthInstallation()->getSessionIndex());
    $user->setProviderID($samlInfo->getNameID()->getspProviderId());
    $user->setAuthenticationServiceName($samlInfo->getAuthenticationServiceID());
    $user->setNameID($samlInfo->getNameID()->getValue());
    $user->setNameIDFormat($samlInfo->getNameID()->getFormat());
    }
    $em=$this->container->get('doctrine')->getManager();
    $em->persist($user);
    $em->flush();
    返回$user;
    }
    公共函数loadUserByUsername($username)
    {
    $repository=$this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');
    $user=$repository->findOneBy(
    数组('username'=>$username)
    );
    如果($user){
    返回$user;
    }
    抛出new\Symfony\Component\Security\Core\Exception\UsernameNotFoundException();
    返回false;
    }
    /**
    *{@inheritardoc}
    */
    公共函数刷新用户(用户界面$user)
    {
    $repository=$this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');
    $newUser=$repository->findOneBy(
    数组('nameID'=>$user->getNameID())
    );
    如果(!$newUser){
    抛出new\Symfony\Component\Security\Core\Exception\UsernameNotFoundException();
    }
    返回$newUser;
    }
    /**
    *{@inheritardoc}
    */
    公共功能支持类($class)
    {
    返回true;
    }
    }
    
    在SamlBundle/Resources/config/services.yml中创建您的服务:

    services:
        SamlToState:
            class: SamlBundle\Models\SamlToState
            arguments: [@service_container]
    
    现在是进行第7步的时候了,交换元数据。按照说明获取SP XML,然后返回IDP。您可以在Federation选项卡上找到“XML到simpleSAMLphp元数据转换器”链接。按照该链接将您的SP XML数据转换为simpleSAMLphp格式。将该数据添加到IDPs元数据文件夹中的saml20-sp-remote.php文件中

    好的,我很确定我忘了什么,但希望这些信息能有所帮助。如果
    services:
        SamlToState:
            class: SamlBundle\Models\SamlToState
            arguments: [@service_container]