kuleuven / authentication-bundle
Symfony3 Bundle for KU Leuven Shibboleth authentication, with LDAP and Person Data API integration
Installs: 119
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=5.6
- psr/log: *
- symfony/config: ^3.1
- symfony/dependency-injection: ^3.1
- symfony/dom-crawler: ^3.1
- symfony/event-dispatcher: ^3.1
- symfony/http-foundation: ^3.1
- symfony/http-kernel: ^3.1
- symfony/ldap: ^3.1
- symfony/security: ^3.1
- symfony/security-bundle: ^3.1
- symfony/templating: ^3.1
README
This bundle adds a shibboleth authentication firewall to your Symfony3 project.
Installation
Download the Bundle
Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:
$ composer require kuleuven/authentication-bundle
This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.
Enable the Bundle
Then, enable the bundle by adding it to the list of registered bundles
in the app/AppKernel.php
file of your project:
<?php // app/AppKernel.php // ... class AppKernel extends Kernel { public function registerBundles() { $bundles = array( // ... new Kuleuven\AuthenticationBundle\KuleuvenAuthenticationBundle(), ); // ... } // ... }
Shibboleth
Setup the Symfony firewall
# app/config/security.yml security: ... providers: ... kuleuven_authentication.service.shibboleth_user_provider: id: kuleuven_authentication.service.shibboleth_user_provider ... firewalls: ... kuleuven_authentication: pattern: ^/secured # change this to your application's secured path stateless: true kuleuven_authentication: ~ logout: path: /logout success_handler: kuleuven_authentication.security.http.logout.handler
By default, the bundle will use a default Shibboleth user provider. This is an in-memory user provider that will get your user on the fly, based on the server attributes.
You can setup the firewall to check specific attribute requirements before authentication. By default, this is set to the Shib-Identity-Provider needed to be 'urn:mace:kuleuven.be:kulassoc:kuleuven.be'.
# app/config/config.yml ... kuleuven_authentication: authentication_attribute_requirements: { Shib-Identity-Provider: 'urn:mace:kuleuven.be:kulassoc:kuleuven.be' }
Setup Shibboleth in the .htaccess file in your public folder
# web/.htaccess # Shibboleth <IfModule mod_shib> AuthType shibboleth Require shibboleth ShibRequireSession On </IfModule>
Change Shibboleth Service Provider settings (optional)
# app/config/config.yml ... kuleuven_authentication: shibboleth_is_secured_handler: true shibboleth_handler_path: /Shibboleth.sso shibboleth_status_path: /Status shibboleth_session_login_path: /Login shibboleth_session_logout_path: /Logout shibboleth_session_logout_target: ~ shibboleth_session_overview_path: /Session shibboleth_username_attribute: Shib-Person-uid shibboleth_authenticated_attribute: Shib-Identity-Provider shibboleth_logout_url_attribute: Shib-logoutURL shibboleth_default_charset: ISO-8859-1
Overwrite Shibboleth server attributes (optional)
The Shibboleth firewall will by default use the server environment. To be succesfully authenticated, at least two attributes should be present:
- the 'Shib-Identity-Provider' attribute will tell you which provider provided your identity
- the 'Shib-Person-uid' attribute contains your identity's uid
If you don't have Shibboleth running locally, you could add these attributes manually to your server environment, or add them to the $_SERVER array in for example your app_dev.php.
####Parameter injector
This bundle however lets you overwrite any attribute from within your parameters.yml, through the '\Kuleuven\AuthenticationBundle\Service\ParameterAttributesProvider' service that uses the 'authentication_attribute_overwrites' parameter to inject an array of server attributes.
By default this feature is disabled, so you have to explicitly enable it.
# app/config/config_dev.yml kuleuven_authentication: ... authentication_attribute_overwrites_enabled: true
Now you can add your overwrites to your parameters.yml.
# app/config/parameters.yml parameters: ... authentication_attribute_overwrites: Shib-Identity-Provider: 'urn:mace:kuleuven.be:kulassoc:kuleuven.be' Shib-Person-uid: '<(string)your-uid>'
The parameter injector will always overwrite any other server attributes, unless you would overwrite the priority of the service. By default the priority is set to -INF.
####Header injector
You could also overwrite specific attributes in your request, through the '\Kuleuven\AuthenticationBundle\Service\HeaderAttributesProvider' service that uses the symfony request headers to inject an array of server attributes.
By default this feature is disabled, so you have to explicitly enable it.
# app/config/config_dev.yml kuleuven_authentication: ... authentication_attribute_headers_enabled: true
Now you can use something like Requestly to overwrite attributes in your application, by sending them as headers with your request.
The header injector will always overwrite any other server attributes, unless you would overwrite the priority of the service. By default the priority is set to -INF.
####LDAP attributes injector
You can use LDAP to request some of the server attributes from a specific person, through the '\Kuleuven\AuthenticationBundle\Service\LdapAttributesProvider' service that uses the 'authentication_attribute_ldap_filter' parameter to inject an LDAP result array of server attributes.
By default this feature is disabled, so you have to explicitly enable it.
# app/config/config_dev.yml kuleuven_authentication: ... authentication_attribute_ldap_enabled: true
Once enabled, you can add your LDAP filter. Make sure the filter is unique enough to only provide one user.
# app/config/parameters.yml parameters: ... authentication_attribute_ldap_filter: {uid: '<(string)your-uid>'}
It might be possible that you also need to enable LDAP - if so, jump to the LDAP chapter further down.
####Custom injector
If you want to add other services to populate your server attributes, they should implement '\Kuleuven\AuthenticationBundle\Service\AttributesInjectionProviderInterface', and should be tagged with 'kuleuven_authentication.shibboleth_attributes_injector'.
# app/config/services.yml ... my_attributes_provider: class: "%my_attributes_provider.class%" tags: - { name: kuleuven_authentication.shibboleth_attributes_injector }
Change the default firewall settings (optional)
For more control, there are two more firewall settings that can be overwritten:
- the 'provider' value defines the user provider - defaults to "kuleuven_authentication.service.shibboleth_user_provider"
- the 'default_roles' value defines some default roles - defaults to an empty array
# app/config/security.yml security: ... firewalls: ... kuleuven_authentication: ... kuleuven_authentication: provider: 'kuleuven_authentication.service.shibboleth_user_provider' default_roles: ~
Overwrite the attribute definitions
By default, the bundle exposes several Shibboleth attributes through the user token KuleuvenUserToken
or the user KuleuvenUser. Attributes can be accessed through getAttribute
,
getSingleAttribute
, getArrayAttribute
or hasAttributeValue
, with their id or aliases as the argument.
The built-in SP variables are:
The KU Leuven provides a long list of usable attributes. A non-exhaustive list:
You can always extend these definitions by adding definitions into the parameter 'authentication_attribute_definitions'.
LDAP
Change LDAP settings (optional)
If you have your own LDAP credentials, you may use those by setting the LDAP parameters. The default settings however should work as long as you are connected to the KU Leuven network.
# app/config/parameters.yml parameters: ldap_rdn: '' ldap_password: '' ldap_base: 'ou=people,dc=kuleuven,dc=be' ldap_domain: 'ldap.kuleuven.be' ldap_port: '389'
Impersonate users (optional)
Through LDAP, we have the possibility to impersonate any KU Leuven member.
Allthough the Shibboleth authentication is stateless itself, for this to work it needs to save a token to the session. You don't need to change the stateless key though, as the Shibboleth authentication will still check the Shibboleth session of the source user to make sure the session stays alive.
To enable this, you need to add an LDAP user provider. However, we also still need our Shibboleth user provider. So let's add a chain_provider, and overwrite the firewall provider. Also add the switch_user attribute, and detect some default_role to check if a user may impersonate.
# app/config/security.yml security: ... providers: chain_provider: chain: providers: [kuleuven_authentication.service.shibboleth_user_provider, kuleuven_authentication.service.shibboleth_via_ldap_user_provider] kuleuven_authentication.service.shibboleth_user_provider: id: kuleuven_authentication.service.shibboleth_user_provider kuleuven_authentication.service.shibboleth_via_ldap_user_provider: id: kuleuven_authentication.service.shibboleth_via_ldap_user_provider ... firewalls: ... kuleuven_authentication: ... kuleuven_authentication: provider: chain_provider default_roles: [ROLE_SHIBBOLETH_AUTHENTICATED] switch_user: { role: ROLE_SHIBBOLETH_AUTHENTICATED, parameter: _switch_user }
Typical development setup
Both using the overwrites and LDAP, there is a very easy setup to enable local development without installing Shibboleth.
Enable the overwrites and provide the overwrite for the Shib-Identity-Provider attribute in config_dev.yml. Also enable LDAP in config_dev.yml.
# app/config/config_dev.yml ... kuleuven_authentication: authentication_attribute_overwrites_enabled: true authentication_attribute_overwrites: {Shib-Identity-Provider: 'urn:mace:kuleuven.be:kulassoc:kuleuven.be'} authentication_attribute_ldap_enabled: true
Add your uid by adding this to your parameters.yml(.dist). It will be ignored in production.
# app/config/parameters.yml.dist ... parameters: authentication_attribute_ldap_filter: {uid: '<(string)your-uid>'}
Extra
There is a default route "/authentication".
Check if you are behind a certain firewall with the FirewallHelper service.
Upcoming
Security
- Make it possible to add your own attribute-map.xml file (including external url) - downloading in compiler pass?
- Find a way to detect which fields are multivalue, instead of hard-coding it into the AttributeDefinitionsProvider
- Add providerKey in token support checks
Logging
- Use one central proxy logger for the authentication bundle
- Implement LoggerAware in some extra classes
Data Collector
- Add authentication (including use_headers), LDAP, PersonDataAPI and impersonation to DataCollector
Switch User
- Instead of overwriting the switchuser_listener, add a new Security Factory
- Add KuleuvenSwitchUserToken
- ShibbolethSwitchUserPersistenceSubscriber should authenticate token in onKernelRequest with ShibbolethAuthenticationProvider
Docker
- Create Docker container with https://shib.kuleuven.be/docs/sp/2.x/install-sp-2.x-windows2008.html
- For KU Leuven: To request a commercial certificate, please refer to: https://certificates.kuleuven.be
- SSL certificates: Download the certificate from http://shib.kuleuven.be/download/metadata/metadata.associatie.kuleuven.be.crt
- Metadata provider: https://shib.kuleuven.be/download/metadata/metadata-kuleuven.xml
- Service providers part of the KU Leuven federation will have to configure the MetadataProvider to get the metadata from https://shib.kuleuven.be/download/metadata/metadata-kuleuven.xml
- For SP's part of the Association KU Leuven federation the URL is https://shib.kuleuven.be/download/metadata/metadata-kulassoc.xml
- For Service Providers part of the K.U.Leuven federation or the Association K.U.Leuven federation, we have configured such an attribute-map: https://shib.kuleuven.be/download/sp/2.x/attribute-map.xml
Extra
- Send notice if LDAP filter returns more than 1 user
- Provide examples: how to add an automatic user save on visit