X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ipsilon%2Fproviders%2Fsaml2idp.py;h=4c2639f7311ac5eaee224872c07acfdc7013644f;hb=ba59365931a4e35226b3d9be216d867ff1549846;hp=efaf67e4a73f9e9e0926026d4b3d787646a99cb6;hpb=6437f6c9385e5e59cb21de7a3addedd904ee2825;p=cascardo%2Fipsilon.git diff --git a/ipsilon/providers/saml2idp.py b/ipsilon/providers/saml2idp.py index efaf67e..4c2639f 100644 --- a/ipsilon/providers/saml2idp.py +++ b/ipsilon/providers/saml2idp.py @@ -8,7 +8,6 @@ from ipsilon.providers.saml2.admin import Saml2AdminPage from ipsilon.providers.saml2.rest import Saml2RestBase from ipsilon.providers.saml2.provider import IdentityProvider from ipsilon.providers.saml2.sessions import SAMLSessionFactory -from ipsilon.providers.saml2.sessions import expire_sessions from ipsilon.tools.certs import Certificate from ipsilon.tools import saml2metadata as metadata from ipsilon.tools import files @@ -131,7 +130,7 @@ class Continue(AuthenticateRequest): return self.auth(login) -class RedirectLogout(LogoutRequest): +class Logout(LogoutRequest): def GET(self, *args, **kwargs): query = cherrypy.request.query_string @@ -159,7 +158,7 @@ class SLO(ProviderPageBase): def __init__(self, *args, **kwargs): super(SLO, self).__init__(*args, **kwargs) self.debug('SLO init') - self.Redirect = RedirectLogout(*args, **kwargs) + self.Redirect = Logout(*args, **kwargs) # one week @@ -215,6 +214,7 @@ class IdpProvider(ProviderBase): self.rest = None self.page = None self.idp = None + self.sessionfactory = None self.description = """ Provides SAML 2.0 authentication infrastructure. """ @@ -272,6 +272,10 @@ Provides SAML 2.0 authentication infrastructure. """ 'default allowed attributes', 'Defines a list of allowed attributes, applied after mapping', ['*']), + pconfig.String( + 'session database url', + 'Database URL for SAML2 sessions', + 'saml2.sessions.db.sqlite'), ) if cherrypy.config.get('debug', False): import logging @@ -281,9 +285,6 @@ Provides SAML 2.0 authentication infrastructure. """ logger.addHandler(lh) logger.setLevel(logging.DEBUG) - bt = cherrypy.process.plugins.BackgroundTask(60, expire_sessions) - bt.start() - @property def allow_self_registration(self): return self.get_config_value('allow self registration') @@ -336,17 +337,30 @@ Provides SAML 2.0 authentication infrastructure. """ return self.get_config_value('default allowed attributes') def get_tree(self, site): - self.idp = self.init_idp() self.page = SAML2(site, self) self.admin = Saml2AdminPage(site, self) self.rest = Saml2RestBase(site, self) return self.page + def used_datastores(self): + # pylint: disable=protected-access + return [self.sessionfactory._ss] + def init_idp(self): idp = None + self.sessionfactory = SAMLSessionFactory( + database_url=self.get_config_value('session database url') + ) + # Schedule cleanups + # pylint: disable=protected-access + bt = cherrypy.process.plugins.BackgroundTask( + 60, self.sessionfactory._ss.remove_expired_sessions + ) + bt.start() # Init IDP data try: - idp = IdentityProvider(self) + idp = IdentityProvider(self, + sessionfactory=self.sessionfactory) except Exception, e: # pylint: disable=broad-except self.debug('Failed to init SAML2 provider: %r' % e) return None @@ -380,13 +394,18 @@ Provides SAML 2.0 authentication infrastructure. """ Logout all SP sessions when the logout comes from the IdP. For the current user only. + + Only use HTTP-Redirect to start the logout. This is guaranteed + to be supported in SAML 2. """ self.debug("IdP-initiated SAML2 logout") us = UserSession() user = us.get_user() - saml_sessions = SAMLSessionFactory() - session = saml_sessions.get_next_logout() + saml_sessions = self.sessionfactory + # pylint: disable=unused-variable + (mech, session) = saml_sessions.get_next_logout( + logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT]) if session is None: return @@ -404,7 +423,8 @@ Provides SAML 2.0 authentication infrastructure. """ # be redirected to when all SP's are logged out. idpurl = self._root.instance_base_url() session_id = "_" + uuid.uuid4().hex.upper() - saml_sessions.add_session(session_id, idpurl, user.name, "") + saml_sessions.add_session(session_id, idpurl, user.name, "", "", + [lasso.SAML2_METADATA_BINDING_REDIRECT]) init_session = saml_sessions.get_session_by_id(session_id) saml_sessions.start_logout(init_session, relaystate=idpurl) @@ -459,6 +479,8 @@ class Installer(ProviderInstaller): help=('Metadata validity period in days ' '(default - %d)' % METADATA_DEFAULT_VALIDITY_PERIOD)) + group.add_argument('--saml2-session-dburl', + help='session database URL') def configure(self, opts, changes): if opts['saml2'] != 'yes': @@ -497,7 +519,11 @@ class Installer(ProviderInstaller): 'idp certificate file': cert.cert, 'idp key file': cert.key, 'idp nameid salt': uuid.uuid4().hex, - 'idp metadata validity': opts['saml2_metadata_validity']} + 'idp metadata validity': opts['saml2_metadata_validity'], + 'session database url': opts['saml2_session_dburl'] or + opts['database_url'] % { + 'datadir': opts['data_dir'], + 'dbname': 'saml2.sessions.db'}} po.save_plugin_config(config) # Update global config to add login plugin