安全基础 #
一、安全组件概述 #
1.1 安全组件功能 #
text
┌─────────────────────────────────────────────────────┐
│ 安全组件功能 │
├─────────────────────────────────────────────────────┤
│ • 认证:验证用户身份 │
│ • 授权:控制访问权限 │
│ • 防火墙:保护应用安全 │
│ • CSRF保护:防止跨站请求伪造 │
│ • 密码加密:安全存储密码 │
│ • 会话管理:安全会话处理 │
└─────────────────────────────────────────────────────┘
1.2 安装安全组件 #
bash
# 安装安全组件
composer require security
二、安全配置 #
2.1 基本配置 #
yaml
# config/packages/security.yaml
security:
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
password_hashers:
App\Entity\User:
algorithm: auto
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
form_login:
login_path: app_login
check_path: app_login
logout:
path: app_logout
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/profile, roles: ROLE_USER }
2.2 用户提供者 #
yaml
# config/packages/security.yaml
security:
providers:
# 实体提供者
app_user_provider:
entity:
class: App\Entity\User
property: email
# 内存提供者
in_memory:
memory:
users:
admin:
password: $2y$13$...
roles: ROLE_ADMIN
2.3 密码加密器 #
yaml
# config/packages/security.yaml
security:
password_hashers:
# 自动选择最佳算法
App\Entity\User:
algorithm: auto
# 指定算法
App\Entity\LegacyUser:
algorithm: bcrypt
cost: 12
三、用户实体 #
3.1 创建用户实体 #
bash
# 使用Maker创建用户实体
php bin/console make:user
# 输出
created: src/Entity/User.php
created: src/Repository/UserRepository.php
updated: config/packages/security.yaml
3.2 用户实体定义 #
php
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 180, unique: true)]
private ?string $email = null;
#[ORM\Column]
private array $roles = [];
#[ORM\Column]
private ?string $password = null;
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): static
{
$this->email = $email;
return $this;
}
public function getUserIdentifier(): string
{
return (string) $this->email;
}
public function getRoles(): array
{
$roles = $this->roles;
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): static
{
$this->roles = $roles;
return $this;
}
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): static
{
$this->password = $password;
return $this;
}
public function eraseCredentials(): void
{
}
}
四、防火墙配置 #
4.1 防火墙基础 #
yaml
# config/packages/security.yaml
security:
firewalls:
# 开发环境防火墙
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# API防火墙
api:
pattern: ^/api/
stateless: true
http_basic: true
# 主防火墙
main:
pattern: ^/
lazy: true
provider: app_user_provider
form_login:
login_path: app_login
check_path: app_login
default_target_path: app_home
logout:
path: app_logout
target: app_home
remember_me:
secret: '%kernel.secret%'
lifetime: 604800
4.2 防火墙选项 #
| 选项 | 说明 |
|---|---|
| pattern | URL匹配模式 |
| provider | 用户提供者 |
| lazy | 延迟加载用户 |
| stateless | 无状态模式 |
| form_login | 表单登录 |
| http_basic | HTTP基本认证 |
| logout | 登出配置 |
| remember_me | 记住我功能 |
五、访问控制 #
5.1 基本访问控制 #
yaml
# config/packages/security.yaml
security:
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/profile, roles: ROLE_USER }
- { path: ^/api, roles: PUBLIC_ACCESS }
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/register, roles: PUBLIC_ACCESS }
5.2 条件访问控制 #
yaml
# config/packages/security.yaml
security:
access_control:
- { path: ^/admin, roles: ROLE_ADMIN, ips: [127.0.0.1, 192.168.0.0/16] }
- { path: ^/api/admin, roles: ROLE_API_ADMIN, methods: [POST, PUT, DELETE] }
- { path: ^/secure, roles: ROLE_USER, host: secure\.example\.com }
5.3 访问控制选项 #
| 选项 | 说明 |
|---|---|
| path | URL路径模式 |
| roles | 所需角色 |
| methods | HTTP方法限制 |
| ips | IP地址限制 |
| host | 主机名限制 |
| allow_if | 表达式条件 |
六、角色管理 #
6.1 角色层次 #
yaml
# config/packages/security.yaml
security:
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_EDITOR]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
6.2 检查角色 #
php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class AdminController extends AbstractController
{
#[Route('/admin', name: 'app_admin')]
#[IsGranted('ROLE_ADMIN')]
public function index(): Response
{
return $this->render('admin/index.html.twig');
}
#[Route('/admin/users', name: 'app_admin_users')]
public function users(): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
return $this->render('admin/users.html.twig');
}
}
6.3 模板中检查角色 #
twig
{# 检查角色 #}
{% if is_granted('ROLE_ADMIN') %}
<a href="{{ path('app_admin') }}">管理后台</a>
{% endif %}
{% if is_granted('ROLE_USER') %}
<p>欢迎, {{ app.user.name }}</p>
{% endif %}
七、CSRF保护 #
7.1 CSRF配置 #
yaml
# config/packages/framework.yaml
framework:
csrf_protection: true
7.2 表单CSRF保护 #
php
<?php
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
class FormController extends AbstractController
{
public function submit(Request $request, CsrfTokenManagerInterface $csrfTokenManager): Response
{
$token = new CsrfToken('form_id', $request->request->get('_token'));
if (!$csrfTokenManager->isTokenValid($token)) {
throw new \Exception('CSRF token is invalid');
}
// 处理表单
}
}
7.3 模板中CSRF令牌 #
twig
<form method="post">
<input type="hidden" name="_token" value="{{ csrf_token('form_id') }}">
<button type="submit">提交</button>
</form>
八、密码处理 #
8.1 密码加密 #
php
<?php
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class RegistrationController extends AbstractController
{
public function register(
Request $request,
UserPasswordHasherInterface $passwordHasher,
EntityManagerInterface $entityManager
): Response {
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$plainPassword = $form->get('plainPassword')->getData();
$hashedPassword = $passwordHasher->hashPassword(
$user,
$plainPassword
);
$user->setPassword($hashedPassword);
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute('app_home');
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form,
]);
}
}
8.2 密码验证 #
php
<?php
class LoginController extends AbstractController
{
public function login(AuthenticationUtils $authenticationUtils): Response
{
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
}
九、安全最佳实践 #
9.1 安全建议 #
text
安全建议:
├── 使用HTTPS
├── 强密码策略
├── 密码加密存储
├── 启用CSRF保护
├── 限制登录尝试
├── 使用安全Cookie
├── 定期更新依赖
└── 安全审计日志
9.2 安全检查 #
bash
# 检查安全漏洞
symfony security:check
# 检查依赖漏洞
composer audit
十、总结 #
本章学习了:
- 安全组件概述
- 安全配置
- 用户实体定义
- 防火墙配置
- 访问控制
- 角色管理
- CSRF保护
- 密码处理
下一章将学习 用户认证。
最后更新:2026-03-28