gpt4 book ai didi

symfony - Symfony2 中的 saml2 身份提供者

转载 作者:行者123 更新时间:2023-12-05 01:01:16 24 4
gpt4 key购买 nike

我必须使用现有的 Symfony 2 应用程序实现和集成 SAML2 身份提供程序 (IdP)。

我发现了一些实现服务提供者 (SP) 但没有实现身份提供者的包,所以我想我可以使用 SimpleSAMLphp library .还有其他解决方案吗?

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

最佳答案

更新

正如 Milos Tomic 在他的评论中提到的,aerialship/lightsaml 被替换为 lightsaml/sp-bundle .您可以找到一个 introduction here .

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

我最近使用 Simplesamlphp 设置了 SAML 解决方案作为 IDP 和 SamlSPBundle作为 SP,一切都运行良好。

我建议先安装 Simplesamlphp,遵循这个 good Documentation here .

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

在 symfony 方面,我创建了一个新的 Bundle 并命名为“SamlBundle”。按照文档(步骤 1 和步骤 2)中的说明下载并安装 SamlSPBundle。

创建您的 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):
# app/config/config.yml
aerial_ship_saml_sp:
driver: orm
sso_state_entity_class: SamlBundle\Entity\SamlUser

更新您的 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;

use SamlBundle\Entity\SamlUser;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use AerialShip\SamlSPBundle\Bridge\SamlSpInfo;
use AerialShip\SamlSPBundle\Security\Core\User\UserManagerInterface as UserManagerInterface;


class SamlToState implements UserManagerInterface
{
/**
* @var ContainerInterface base bundle container
*/
public $container;

/**
* Constructor with DependencyInjection params.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
*/
public function __construct(ContainerInterface $container) {
$this->container = $container;
}

/**
* {@inheritdoc}
*/
public function loadUserBySamlInfo(SamlSpInfo $samlInfo)
{
$user = $this->loadUserByTargetedID($samlInfo->getAttributes()['eduPersonTargetedID']->getFirstValue());

return $user;
}

private function loadUserByTargetedID($targetedID) {
$repository = $this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');

$user = $repository->findOneBy(
array('targetedID' => $targetedID)
);

if ($user) {
return $user;
}

throw new \Symfony\Component\Security\Core\Exception\UsernameNotFoundException();
}

/**
* {@inheritdoc}
*/
public function createUserFromSamlInfo(SamlSpInfo $samlInfo)
{
$repository = $this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');

$user = $repository->findOneBy(
array('nameID' => $samlInfo->getNameID()->getValue())
);

if ($user) {
$user->setUsername($samlInfo->getAttributes()['eduPersonPrincipalName']->getFirstValue());
$user->setTargetedID($samlInfo->getAttributes()['eduPersonTargetedID']->getFirstValue());
$user->setRoles($samlInfo->getAttributes()['role']->getFirstValue());
} else {
$user = new SamlUser();
$user->setUsername($samlInfo->getAttributes()['eduPersonPrincipalName']->getFirstValue());
$user->setTargetedID($samlInfo->getAttributes()['eduPersonTargetedID']->getFirstValue());
$user->setRoles($samlInfo->getAttributes()['role']->getFirstValue());
$user->setSessionIndex($samlInfo->getAuthnStatement()->getSessionIndex());

$user->setProviderID($samlInfo->getNameID()->getSPProvidedID());
$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();

return $user;
}

public function loadUserByUsername($username)
{
$repository = $this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');

$user = $repository->findOneBy(
array('username' => $username)
);

if ($user) {
return $user;
}

throw new \Symfony\Component\Security\Core\Exception\UsernameNotFoundException();
return false;
}

/**
* {@inheritdoc}
*/
public function refreshUser(UserInterface $user)
{
$repository = $this->container->get('doctrine')->getManager()->getRepository('MrmPosSamlBundle:SamlUser');

$newUser = $repository->findOneBy(
array('nameID' => $user->getNameID())
);

if (!$newUser) {
throw new \Symfony\Component\Security\Core\Exception\UsernameNotFoundException();
}

return $newUser;
}

/**
* {@inheritdoc}
*/
public function supportsClass($class)
{
return true;
}

}

在 SamlBundle/Resources/config/services.yml 中创建您的服务:
services:
SamlToState:
class: SamlBundle\Models\SamlToState
arguments: [@service_container]

现在是第 7 步,交换元数据的时候了。按照描述获取 SP XML 并返回给您的 IDP。您可以在“联合”选项卡上找到“XML 到 simpleSAMLphp 元数据转换器”链接。按照该链接并将您的 SP XML 数据转换为 simpleSAMLphp 格式。将该数据添加到 IDP 元数据文件夹中的 saml20-sp-remote.php 文件中。

好的,我很确定我忘记了一些东西,但希望这些信息会有所帮助。如果您遇到困难,欢迎回复我。

关于symfony - Symfony2 中的 saml2 身份提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28527383/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com