
本文档介绍如何使用 Symfony 框架和 SAML 2.0 单点登录 (SSO) 来保护静态网站的 Twig 路由。我们将使用 hslavich/OneloginSamlBundle 集成 SAML 认证,并配置 Symfony 的安全组件来限制对特定路由的访问,确保只有经过身份验证的用户才能访问这些页面。
本教程将指导你如何设置一个 Symfony 项目,该项目通过 SAML 2.0 SSO 提供静态 Twig 路由。我们将使用 hslavich/OneloginSamlBundle 来简化 SAML 集成。
首先,使用 Composer 安装 hslavich/OneloginSamlBundle:
composer require hslavich/onelogin-saml-bundle
根据你的服务提供商 (SP) 和身份提供商 (IdP) 的配置,填写 config/packages/hslavich_onelogin_saml.yaml 文件。请参考该 Bundle 的 README.md 文件获取详细的配置说明。
一个重要的注意事项是,baseurl 配置值应该设置为应用程序的域名,并 附加 /saml。例如:http://myapp.com/saml。这是因为 Bundle 中存在一个 bug,它会移除最后一个路径值(例如 /saml/acs 中的 acs)和域名之间的所有内容。
一个典型的配置示例如下:
# config/packages/hslavich_onelogin_saml.yaml
hslavich_onelogin_saml:
sp:
entityid: "your_sp_entity_id"
assertion_consumer_service:
url: "http://myapp.com/saml/acs"
single_logout_service:
url: "http://myapp.com/saml/sls"
NameIDFormat: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
x509cert: "YOUR_SP_CERTIFICATE"
privateKey: "YOUR_SP_PRIVATE_KEY"
idp:
entityid: "your_idp_entity_id"
single_sign_on_service:
url: "your_idp_sso_url"
single_logout_service:
url: "your_idp_slo_url"
x509cert: "YOUR_IDP_CERTIFICATE"
security:
username_mapper: Hslavich\OneloginSamlBundle\Security\User\AttributeUserMapper请确保将 YOUR_SP_CERTIFICATE, YOUR_SP_PRIVATE_KEY, your_idp_entity_id, your_idp_sso_url, your_idp_slo_url 和 YOUR_IDP_CERTIFICATE 替换为你的实际值。
更新 config/packages/security.yaml 文件以集成 SAML 认证。
security:
enable_authenticator_manager: true
providers:
saml_provider:
saml:
user_class: App\Security\User
default_roles:
- ROLE_USER
app_user_provider:
id: App\Security\UserProvider # 可选,如果你需要自定义 UserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
app:
saml:
provider: saml_provider
username_attribute: eduPersonTargetedID # 映射 SAML 属性到用户名
check_path: saml_acs # SAML Assertion Consumer Service 路径
login_path: saml_login # SAML 登录路径
logout:
path: saml_logout # SAML 登出路径
main:
lazy: true
provider: app_user_provider # 可选,如果你需要自定义 UserProvider
access_control:
- { path: ^/saml/login, roles: PUBLIC_ACCESS } # 允许匿名访问 SAML 登录路径
- { path: ^/saml/metadata, roles: PUBLIC_ACCESS } # 允许匿名访问 SAML 元数据路径
- { path: ^/, roles: ROLE_USER } # 所有其他路径需要 ROLE_USER 角色解释:
创建一个 App\Security\User 类,实现 Symfony\Component\Security\Core\User\UserInterface 接口。这个类将代表经过 SAML 认证的用户。
<?php
namespace App\Security;
use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface
{
private $username;
private $roles;
public function __construct(string $username, array $roles = [])
{
$this->username = $username;
$this->roles = $roles;
}
public function getUsername(): string
{
return $this->username;
}
public function getRoles(): array
{
return $this->roles;
}
public function getPassword(): ?string
{
return null; // SAML 认证不需要密码
}
public function getSalt(): ?string
{
return null; // SAML 认证不需要 salt
}
public function eraseCredentials()
{
// 如果需要,可以在这里清除敏感数据
}
public function getUserIdentifier(): string
{
return $this->username;
}
}如果你需要自定义用户加载逻辑,可以创建一个 App\Security\UserProvider 类,实现 Symfony\Component\Security\Core\User\UserProviderInterface 接口。
<?php
namespace App\Security;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
class UserProvider implements UserProviderInterface
{
public function loadUserByIdentifier(string $identifier): UserInterface
{
// 在这里实现你的用户加载逻辑
// 例如,从数据库或 API 获取用户信息
// 为了简单起见,我们直接创建一个 User 对象
return new User($identifier, ['ROLE_USER']);
}
public function refreshUser(UserInterface $user): UserInterface
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Invalid user class "%s".', get_class($user)));
}
return $this->loadUserByIdentifier($user->getUserIdentifier());
}
public function supportsClass(string $class): bool
{
return User::class === $class;
}
public function loadUserByUsername(string $username): UserInterface
{
return $this->loadUserByIdentifier($username);
}
}创建你的 Twig 模板和控制器来显示静态内容。例如:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class HomeController extends AbstractController
{
#[Route('/', name: 'home')]
public function index(): Response
{
return $this->render('home/index.html.twig', [
'message' => 'Welcome to the secured area!',
]);
}
}{# templates/home/index.html.twig #}
<h1>{{ message }}</h1>
<p>You are logged in!</p>
<a href="{{ path('saml_logout') }}">Logout</a>现在,访问你的应用程序的根路径(例如 http://myapp.com/)。你将被重定向到 IdP 进行身份验证。成功认证后,你将被重定向回应用程序,并可以访问受保护的页面。
通过以上步骤,你已经成功配置了一个 Symfony 项目,该项目使用 hslavich/OneloginSamlBundle 和 SAML 2.0 SSO 来保护静态 Twig 路由。 /saml/login 和 /saml/metadata 路径可以公开访问,而所有其他路由都需要 ROLE_USER 角色。 用户成功通过 IdP 身份验证后,将被重定向回来并获得会话,然后可以访问站点中的所有路由。
注意事项:
以上就是使用 Symfony 和 SAML 2.0 SSO 保护静态 Twig 路由的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号