我有一个问题。我需要通过我的应用程序中的 SSO 响应对用户进行身份验证。 我有一个有效的 SSO 响应,我在身份验证器中传递了 onAuthenticationSuccess,但在我的控制器中,当我尝试获取我的用户时,它返回 null,我可以在工具栏中看到我没有经过身份验证。
这是我的 security.yaml :
security:
providers:
app_admin_provider:
entity:
class: App\Entity\Admin
property: username
firewalls:
saml_login:
pattern: /general/saml/
security: true
lazy: true
provider: app_admin_provider
custom_authenticators:
- App\Security\SamlAuthenticator
这是我的 SamlAuthenticator :
class SamlAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
public function __construct(private EntityManagerInterface $entityManager) {}
public function supports(Request $request): bool
{
if ($request->request->get('SAMLResponse')) {
return true;
}
return false;
}
public function authenticate(Request $request): Passport
{
$dataSSO = $this->getSSOReponse($request);
$request->getSession()->set(Security::LAST_USERNAME, $dataSSO['email']);
return new SelfValidatingPassport(new UserBadge($dataSSO['email'], function($username) {
$admin = $this->entityManager->getRepository(Admin::class)->findOneBy(['username' => $username]);
if (! $admin) {
throw new UserNotFoundException();
}
return $admin;
}));
}
public function onAuthenticationSuccess(Request $request,TokenInterface $token,string $firewallName): Response|null
{
return null;
}
}
在我的“onAuthenticationSuccess”方法中,我可以在令牌中看到用户。 但随后在控制器中用户未经过身份验证。
有人可以帮我吗?
在“身份验证”方法中,我尝试了不同的方法来创建护照。
return new SelfValidatingPassport(new UserBadge($dataSSO['email']);
我还尝试将逻辑放入“onAuthenticationSuccess”方法中。
没有任何效果。
代码在处理身份验证方面似乎很好。
问题:您能否确认是否使用了正确的防火墙进行身份验证?您是否配置了多个防火墙?
您验证身份验证的 URL 是否以 /general/saml/ 为前缀,例如: http://yourapplication.com/general/saml/welcome ?
如果没有,这可能就是问题所在。
一些改进:考虑将类扩展从 AbstractLoginFormAuthenticator 更改为 AbstractAuthenticator,因为 SSO 不是 LoginForm。这可能不会导致这里的问题,但这是一个很好的做法。
另外,最好不要返回null。由于您使用的是 TargetPath 特征,因此您可以实现以下示例代码:
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('index_from_your_firewall_route'));
}