Closed Jaswinder00 closed 7 years ago
You don't need separate firewall for saml login and discovery. It must be within fw lightsam is configured in order to work.
I would suggest you first to trough all getting started steps and once that works you add form listener to the same fw using the same user provider
Thanks for responding! If I remove the fw for login and discovery, I get redirected back to /saml/login page with the same error indicating net::ERR_TOO_MANY_REDIRECTS. I followed the directions to setup, but something is lacking. Any other thoughts?
Not sure what you see as a problem. Starting saml auth instead of form auth? Which listener you want to respond first? Try reordering listeners or define an entry point.
Though... if you wish saml first, and complaining about it not working, then there is a case of too many redirects if saml listener does not authenticate a user from #19. If that's the case, until it's fixed you can create user creator to return dummy/non-persisted user w/out roles
Please explain the use cases you need, and why you need two login methods
The requirement is to login to the system using two methods: Saml and Direct (for example admin). I want Saml firewall to be first. I do not have the UserCreator class as it is optional. We may not want users to be created as of you. Just know that the logs show that user is authenticated but it goes to infinite loop. Here are the error logs if this helps:
[2016-08-10 11:32:53] app.DEBUG: Known issuer resolved: "http://idp.haven.com/simplesaml/saml2/idp/metadata.php" {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Profile\\Inbound\\Message\\ResolvePartyEntityIdAction","top_context_id":"000000003c9fd4e400000000802115ad","partyEntityId":"http://idp.haven.com/simplesaml/saml2/idp/metadata.php"} [][2016-08-10 11:32:53] app.DEBUG: Message signature validated with key "/C=US/ST=Maryland/L=Bethesda/O=CompanyName/OU=Healthcare/CN=HAVENIDP/emailAddress=testuser@gmail.com, /C=US/ST=Maryland/L=Bethesda/O=CompanyName/OU=Healthcare/CN=HAVENIDP/emailAddress=testuser@gmail.com" {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Profile\\Inbound\\Message\\MessageSignatureValidatorAction","top_context_id":"000000003c9fd4e400000000802115ad","credential":"[object] (LightSaml\\Credential\\X509Credential: {})"} []
[2016-08-10 11:32:53] app.DEBUG: Response has no encrypted assertions {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Profile\\Inbound\\Response\\DecryptAssertionsAction","top_context_id":"000000003c9fd4e400000000802115ad"} []
[2016-08-10 11:32:53] app.DEBUG: Known assertion issuer: "http://idp.haven.com/simplesaml/saml2/idp/metadata.php" {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Assertion\\Inbound\\KnownAssertionIssuerAction","top_context_id":"000000003c9fd4e400000000802115ad"} []
[2016-08-10 11:32:53] doctrine.DEBUG: SELECT t0.assertion_id AS assertion_id_1, t0.entity_id AS entity_id_2, t0.expiry_time AS expiry_time_3, t0.id AS id_4 FROM id_entry t0 WHERE t0.entity_id = ? AND t0.assertion_id = ? ["http://idp.haven.com/simpl [...]","_44a9bb104749246a8648fdf7c [...]"] []
[2016-08-10 11:32:53] doctrine.DEBUG: SELECT t0.assertion_id AS assertion_id_1, t0.entity_id AS entity_id_2, t0.expiry_time AS expiry_time_3, t0.id AS id_4 FROM id_entry t0 WHERE t0.entity_id = ? AND t0.assertion_id = ? ["http://idp.haven.com/simpl [...]","_44a9bb104749246a8648fdf7c [...]"] []
[2016-08-10 11:32:53] doctrine.DEBUG: "START TRANSACTION" [] []
[2016-08-10 11:32:53] doctrine.DEBUG: INSERT INTO id_entry (assertion_id, entity_id, expiry_time) VALUES (?, ?, ?) {"1":"_44a9bb104749246a8648fdf7c [...]","2":"http://idp.haven.com/simpl [...]","3":"2016-08-10 15:37:52"} []
[2016-08-10 11:32:53] doctrine.DEBUG: "COMMIT" [] []
[2016-08-10 11:32:53] app.DEBUG: Assertion signature validated with key "/C=US/ST=Maryland/L=Bethesda/O=CompanyName/OU=Healthcare/CN=HAVENIDP/emailAddress=testuser@gmail.com, /C=US/ST=Maryland/L=Bethesda/O=CompanyName/OU=Healthcare/CN=HAVENIDP/emailAddress=testuser@gmail.com" {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Assertion\\Inbound\\AssertionSignatureValidatorAction","top_context_id":"000000003c9fd4e400000000802115ad","credential":"[object] (LightSaml\\Credential\\X509Credential: {})"} []
[2016-08-10 11:32:53] app.DEBUG: Removed request state "_d7f76b33d97bb001769b3f0de2980383587137af0d" {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Profile\\FlushRequestStatesAction","top_context_id":"000000003c9fd4e400000000802115ad"} []
[2016-08-10 11:32:53] app.DEBUG: Request state "_d7f76b33d97bb001769b3f0de2980383587137af0d" does not exist {"profile_id":"sso_sp_receive_response","own_role":"sp","action":"LightSaml\\Action\\Profile\\FlushRequestStatesAction","top_context_id":"000000003c9fd4e400000000802115ad"} []
[2016-08-10 11:32:53] doctrine.DEBUG: SELECT t0.email AS email_1, t0.password AS password_2, t0.firstname AS firstname_3, t0.lastname AS lastname_4, t0.isactive AS isactive_5, t0.created_timestamp AS created_timestamp_6, t0.id AS id_7, t0.role_id AS role_id_8 FROM user t0 WHERE t0.email = ? LIMIT 1 ["samluser@gmail.com"] []
[2016-08-10 11:32:53] security.INFO: User has been authenticated successfully. {"username":"samluser@gmail.com"} []
[2016-08-10 11:32:53] security.DEBUG: Stored the security token in the session. {"key":"_security_secured_area"} []
[2016-08-10 11:32:53] request.INFO: Matched route "dc_gov_haven_admin". {"route_parameters":{"_controller":"DCGov\\HavenBundle\\Controller\\DefaultController::indexAction","_route":"dc_gov_haven_admin"},"request_uri":"http://dev.haven.com/app_dev.php/profile"} []
[2016-08-10 11:32:53] security.DEBUG: Read existing security token from the session. {"key":"_security_secured_area"} []
[2016-08-10 11:32:53] doctrine.DEBUG: SELECT t0.email AS email_1, t0.password AS password_2, t0.firstname AS firstname_3, t0.lastname AS lastname_4, t0.isactive AS isactive_5, t0.created_timestamp AS created_timestamp_6, t0.id AS id_7, t0.role_id AS role_id_8 FROM user t0 WHERE t0.id = ? [3] []
[2016-08-10 11:32:53] security.DEBUG: User was reloaded from a user provider. {"username":"samluser@gmail.com","provider":"Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider"} []
[2016-08-10 11:32:53] 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 /var/www/safehaven/app/cache/dev/classes.php:2728)"} []
[2016-08-10 11:32:53] security.DEBUG: Calling Authentication entry point. [] []
[2016-08-10 11:32:53] security.DEBUG: Stored the security token in the session. {"key":"_security_secured_area"} []
[2016-08-10 11:32:53] request.INFO: Matched route "lightsaml_sp.login". {"route_parameters":{"_controller":"LightSaml\\SpBundle\\Controller\\DefaultController::loginAction","_route":"lightsaml_sp.login"},"request_uri":"http://dev.haven.com/app_dev.php/saml/login"} []
[2016-08-10 11:32:53] security.DEBUG: Read existing security token from the session. {"key":"_security_secured_area"} []
[2016-08-10 11:32:53] doctrine.DEBUG: SELECT t0.email AS email_1, t0.password AS password_2, t0.firstname AS firstname_3, t0.lastname AS lastname_4, t0.isactive AS isactive_5, t0.created_timestamp AS created_timestamp_6, t0.id AS id_7, t0.role_id AS role_id_8 FROM user t0 WHERE t0.id = ? [3] []
[2016-08-10 11:32:53] security.DEBUG: User was reloaded from a user provider. {"username":"samluser@gmail.com","provider":"Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider"} []
Any thoughts on the next steps or things that I can try?
security config is not whole... providers are missing
You didn't document what is dc_gov_haven_admin
route and which firewall it belongs to
Logs says on 2016-08-10 11:32:53 user was reloaded from Symfony\Bridge\Doctrine\Security\User\EntityUserProvider and AuthenticationException was thrown - No Authentication Provider found for token of class \"LightSaml\SpBundle\Security\Authentication\Token\SamlSpToken
So, it seems, during authentication saml listener creates SamlSpToken
but security on dc_gov_haven_admin
route seems not to include saml listener to recognize that token.
Put code in between 3 backticks - it's more readable
The dc_gov_haven_admin route simply points to the home page. here is how I have it defined in the routing.yml file:
dc_gov_haven_homepage: path: / defaults: { _controller: "DCGovHavenBundle:Default:index" }
I am not sure if I understand your comment. How do I include the saml listener into dc_gov_haven_admin route security?
Firewalls react only on specific url pattern. In each firewall different security listeners are configured. Depending on the route url, different firewall will be chosen, hence different security listeners will react.
Now I saw, in the log trace, the route dc_gov_haven_admin
is /profile
and not /
as you say.... which is dc_gov_haven_homepage
.
Error message that there were no Authentication Provider for SamlSpToken
on url /profile
means that url pattern does not fit a firewall where light_saml_sp listener
was configured.
Paste your whole config/security.yml
file as it was when you got that log trace with exception.
I have changed the target route to be / for testing and did not work. Here is the full security.yml file
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
DCGov\HavenBundle\Entity\User:
algorithm: bcrypt
cost: 12
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
chain_provider:
chain:
providers: [db_provider,in_memory]
db_provider:
entity:
class: DCGov\HavenBundle\Entity\User
property: email
in_memory:
memory:
users:
jsingh@gmail.com:
password: pa$$123
roles: 'ROLE_ADMIN'
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
light_saml_sp:
provider: db_provider # user provider name configured in step 9
user_creator: user_creator # name of the user creator service created in step 10
login_path: /saml/login
check_path: /saml/login_check
default_target_path: /
form_login:
login_path: /admin/login
check_path: /admin/login_check
default_target_path: /
remember_me: true
logout:
path: /logout
target: /
access_control:
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/saml/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/profile, roles: ROLE_USER }
It looks fine... one firewall on /
. I'm not sure why you're getting at AuthenticationProviderManager::authenticate()
on already authenticated token on the /
route, when it's not an authentication route neither for saml nor form listener.
You could place brakepoints on app/cache/dev/classes.php line foreach ($this->providers as $provider) {
few lines above your line 2728 where that exception is throws an see which providers are called, and also check the stack trace to see which listener called authentication at the first place.
Then next brakepoint on Symfony\Component\Security\Http\Firewall::onKernelRequest()
on the foreach ($listeners as $listener) {
line and see which listeners are used.
In any case I have modified the DemoSP app to have two login methods just like in your case, at it works fine. Inspect that code and compare to yours... there must be some difference you're missing.
Thanks for looking into this! I have tried debugging the code, comparing the DemoSP app that you have put up. I also compared the SP-Bundle code implementation with Symfony Custom Providers (http://symfony.com/doc/current/security/custom_authentication_provider.html). So far, no luck. One thing I also notice that token is that the SamlSP is not authenticated from Symfony profile. I will continue with debugging this code. Meanwhile, if you have other suggestions, please let me know.
So, I have finally able to resolve this issue. Basically, if the user exists but it is not authenticated, it creates a constant loop between homepage and login page when using saml. I resolved this issue by implementing the EquatableInterface interface in the User class. Please indicate the same in your docs as it may help someone running into this issue. Thanks for your help!
@Jaswinder00, you have the similar issue we had earlier. Actually, when IDP authenticate and user fail to authorize in SP (your app), it keep looping between IDP and SP. Because IDP inform your credential are valid but SP reject as user not found for authorization. I solved this issue in my app by authorizing these users without any role OR dummy role. This will let SP throws error 403 not authorized.
@INSEAD-asim I have not tested the solution that you mentioned, but we need roles to authorize the users. The issue I was having with loop within the Symfony routes after the user was authenticated by both IDP and SP. But, thanks for your response.
@Jaswinder00 have you managed to make it work? Can we close the issue or there are some new insights?
Yes. I got it resolved. Please close this issue.
On Tuesday, September 20, 2016, Milos Tomic notifications@github.com wrote:
@Jaswinder00 https://github.com/Jaswinder00 have you managed to make it work? Can we close the issue or there are some new insights?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lightSAML/SpBundle/issues/25#issuecomment-248222867, or mute the thread https://github.com/notifications/unsubscribe-auth/ABpO7sUHVm1sfs3gDN8TMyPmvAb52lNdks5qr4h7gaJpZM4JgDfd .
Hi, I am running into an issue with setting up Authentication in Symfony 2.8 with Saml plugin (https://www.lightsaml.com/SP-Bundle/Getting-started/). Problem: I want to able to login via SAML and via going to admin page. The /admin/login page works fine, I see the user authenticated from the database. However, when I try to go through the Saml process, I always land on the /discovery page. When I see the logs, I do see the user is authenticated, but the page is redirected to discovery page. So, I think I have something not correctly configured in the security settings. Please let me know if you can help.
Here are the settings from config/security.yml file: