Closed gabyquiles closed 7 years ago
We have the same issue and I have debugged it in my own case. What happens is that the authentication is actually successful but when the SamlSpToken is stored in the tokenstorage (which is produced when authenticating with a SamlSpRequestToken) any subsequent request authorizations in the AuthenticationProviderManagers cannot find a provider that supports a SamlSpToken. The LightSamlSpAuthenticationProvider only supports only SamlSpRequestTokens.
@gabyquiles did you manage to find a fix or workaround?
Seem to be having the same issue.
When I try to authenticate as a user that already exists within my Symfony project, the SAML auth and login works as intended. If I attempt to access a secured path as a first-time user of the project, the user is correctly created in the database but there's a redirect loop between the secured path and /saml/login_check.
I look at my env log and see the following:
[2017-03-01 22:52:17] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\Component\Security\Core\Exception\ProviderNotFoundException(code: 0): No Authentication Provider found for token of class \"LightSaml\SpBundle\Security\Authentication\Token\SamlSpToken\". at C:\MyProject\var\cache\dev\classes.php:4633)"} []
Does anyone have any pointers on how I can fix this?
@superhaggis
I eventually applied the following patch. Let me know if it works for you.
diff -r abcd086bd6d8 -r fc4c44f5b626 vendor/lightsaml/sp-bundle/src/LightSaml/SpBundle/Security/Authentication/Provider/LightsSamlSpAuthenticationProvider.php
--- a/vendor/lightsaml/sp-bundle/src/LightSaml/SpBundle/Security/Authentication/Provider/LightsSamlSpAuthenticationProvider.php Tue Jan 03 13:05:39 2017 +0100
+++ b/vendor/lightsaml/sp-bundle/src/LightSaml/SpBundle/Security/Authentication/Provider/LightsSamlSpAuthenticationProvider.php Wed Jan 04 00:44:10 2017 +0100
@@ -123,9 +123,12 @@
$this->userChecker->checkPostAuth($user);
}
- $attributes = $this->getAttributes($token);
+ if($token instanceof SamlSpResponseToken)
+ $attributes = $this->getAttributes($token);
+ else
+ $attributes = $token->getAttributes();
- if ($this->tokenFactory) {
+ if ($this->tokenFactory && $token instanceof SamlSpResponseToken) {
$result = $this->tokenFactory->create(
$this->providerKey,
$attributes,
@@ -153,7 +156,7 @@
*/
public function supports(TokenInterface $token)
{
- return $token instanceof SamlSpResponseToken;
+ return $token instanceof SamlSpToken;
}
/**
@@ -163,15 +166,19 @@
*
* @throws UsernameNotFoundException
*/
- private function loadUser(SamlSpResponseToken $token)
+ private function loadUser(SamlSpToken $token)
{
- if (null === $this->usernameMapper || null === $this->userProvider) {
- throw new UsernameNotFoundException();
- }
+ if($token instanceof SamlSpResponseToken) {
+ if (null === $this->usernameMapper || null === $this->userProvider) {
+ throw new UsernameNotFoundException();
+ }
- $username = $this->usernameMapper->getUsername($token->getResponse());
+ $username = $this->usernameMapper->getUsername($token->getResponse());
- $user = $this->userProvider->loadUserByUsername($username);
+ $user = $this->userProvider->loadUserByUsername($username);
+ } else {
+ $user = $token->getUser();
+ }
if (false === $user instanceof UserInterface) {
throw new \LogicException('User provider must return instance of UserInterface');
I'm unable to reproduce error ProviderNotFoundException(code: 0): No Authentication Provider found for token of class "LightSaml\SpBundle\Security\Authentication\Token\SamlSpToken", no matter what I try. Which Symfony version are you getting that on? How do you get it? Paste whole log so I can see what's before that. Please, provide more description on how I can reproduce it.
I have reproduced following loop: secured_page -> login_path -> IDP -> check_path -> login_path -> IDP -> check_path -> login_path ...
In summary, I found that when you have all of these:
failure_path
(Symfony's security firewall option)force
defaulting to false
(LightSAML's security firewall option)you will get a that loop with IDP. If you change any single one of those you will not get a loop.
With user creator service set as explained in https://www.lightsaml.com/SP-Bundle/Getting-started/ when user in not found by user provider (UsernameNotFoundException
thrown), and when user creator creates the user and saves it, it's working as expected - that new user is logged in.
If I try w/out user creator and with force
option false
(in app/config/security.yml
commented line firewalls.main.light_saml_sp.user_creator
) then LightsSamlSpAuthenticationProvider
throws AuthenticationException
which evetually is handled by Symfony's DefaultAuthenticationFailureHandler::onAuthenticationFailure
which creates RedirectResponse
with /saml/login
path since it find no value for failure_path
option, and defaults to login_path
option.
When I try w/out user creator, but with force
option true
, LightsSamlSpAuthenticationProvider
creates token w/out roles, and if trying to open secured route (one requiring ROLE_USER, or ROLE_ADMIN for example) I get normal 403 Access denied, w/out any redirection loop.
If I set failure_path
option, once lightsmal auth proviuder throws auth exception, Symfony will redirect to that given path.
If you find any case I didn't cover, please provide full description on how I can reproduce it, or describe the debug trace.
I can change that and avoid loop in misconfiguration, either by
1) throwing some other exception type that Symfony will not handle (and make RedirectResponse
to login_path
), or
2) setting force
option default value to true
so token w/out roles will be created
Any preferences or some other idea?
@meDavid your fix seems fine to make auth provider support both SamlSpResponseToken
and SamlSpToken
, but I don't understand how can it be called to authenticate or checked to support SamlSpToken
. Can you describe the case when you get that? Once SamlSpToken
is created it's always authenticated and symfony should not call auth providers anymore to authenticate it.
I'm trying to configure this bundle, but I'm having the problem that when I try to login it ends up in an infinite redirection loop. I have my own Id Provider and I registered this installation as an SP with AssertionConsumerService as /saml/login_check and the SingleLogoutService as /logout.
Or there is a way to set up this bundle as my own IdP so that other service can authenticate against it.
Thanks for your help