saml2: begin slo implementation
This commit is contained in:
parent
765b526c6e
commit
bcb29a4cc2
|
@ -28,7 +28,10 @@ class SAML2Auth(AuthForm):
|
|||
lasso.SAML2_METADATA_BINDING_POST ,
|
||||
self.config.END_POINTS_PATH['single_sign_on_post']
|
||||
),
|
||||
)
|
||||
('SingleLogoutService',
|
||||
lasso.SAML2_METADATA_BINDING_REDIRECT,
|
||||
'/singleLogout', '/singleLogoutReturn'),
|
||||
)
|
||||
self.metadata_options = { 'key': self.config.SAML_SIGNATURE_PUBLIC_KEY }
|
||||
super(SAML2Auth, self).__init__(form_values, site_name)
|
||||
|
||||
|
@ -108,7 +111,7 @@ class SAML2Auth(AuthForm):
|
|||
return str(metagen)
|
||||
|
||||
def sso(self, env, values, request, response):
|
||||
target_idp = None
|
||||
target_idp = self.config.IDP_METADATA
|
||||
metadata_file_path = self._get_idp_metadata_file_path()
|
||||
if not metadata_file_path:
|
||||
return _500('sso', 'Unable to load provider.')
|
||||
|
@ -145,6 +148,37 @@ class SAML2Auth(AuthForm):
|
|||
return _500('sso', 'Enable to perform sso by redirection.')
|
||||
return _302(login.msgUrl)
|
||||
|
||||
def slo(self, env, values, request, response):
|
||||
logger.debug('saml2_slo: new slo request')
|
||||
target_idp = self.config.IDP_METADATA
|
||||
metadata_file_path = self._get_idp_metadata_file_path()
|
||||
logger.debug('saml2_slo: target idp %s' % target_idp)
|
||||
logger.debug('saml2_slo: metadata file path %s' % metadata_file_path)
|
||||
|
||||
server = create_server(self._get_metadata(env),
|
||||
self.config.SAML_SIGNATURE_PRIVATE_KEY)
|
||||
if not server:
|
||||
return _500('saml2_slo', 'Error creating server object.')
|
||||
logger.debug('saml2_slo: mandaye server object created')
|
||||
server.addProvider(lasso.PROVIDER_ROLE_IDP, metadata_file_path)
|
||||
logout = lasso.Logout(server)
|
||||
if not logout:
|
||||
return _500('saml2_slo', 'Error creating logout object.')
|
||||
try:
|
||||
logout.initRequest(target_idp, lasso.HTTP_METHOD_REDIRECT)
|
||||
except:
|
||||
logger.critical('sp_slo: init request error')
|
||||
return _500('saml2_slo', 'init request error')
|
||||
try:
|
||||
logout.buildRequestMsg()
|
||||
except:
|
||||
logger.critical('sp_slo: build request error')
|
||||
return _500('saml2_slo', 'build request error')
|
||||
logger.info('sp_slo: sp_slo by redirect')
|
||||
#save_key_values(logout.request.id,
|
||||
# logout.dump(), provider_id, next)
|
||||
return _302(logout.msgUrl)
|
||||
|
||||
def single_sign_on_post(self, env, values, request, response):
|
||||
target_idp = None
|
||||
metadata_file_path = self._get_idp_metadata_file_path()
|
||||
|
@ -197,6 +231,76 @@ class SAML2Auth(AuthForm):
|
|||
|
||||
return _302(values['next_url'])
|
||||
|
||||
def singleLogout(self, env, values, request, response):
|
||||
'''
|
||||
Single Logout IdP initiated by Redirect
|
||||
'''
|
||||
query = get_saml2_query_request(request)
|
||||
if not query:
|
||||
return http_response_forbidden_request('singleLogout: \
|
||||
Unable to handle Single Logout by Redirect without request')
|
||||
|
||||
server = build_service_provider(request)
|
||||
if not server:
|
||||
return http_response_forbidden_request('singleLogout: \
|
||||
Service provider not configured')
|
||||
|
||||
logout = lasso.Logout(server)
|
||||
provider_loaded = None
|
||||
while True:
|
||||
try:
|
||||
logout.processRequestMsg(query)
|
||||
break
|
||||
except (lasso.ServerProviderNotFoundError,
|
||||
lasso.ProfileUnknownProviderError):
|
||||
provider_id = logout.remoteProviderId
|
||||
provider_loaded = load_provider(request, provider_id,
|
||||
server=server, sp_or_idp='idp')
|
||||
|
||||
if not provider_loaded:
|
||||
message = _('singleLogout: provider %r unknown') % provider_id
|
||||
return error_page(request, message, logger=logger)
|
||||
else:
|
||||
continue
|
||||
except lasso.Error, error:
|
||||
logger.error('singleLogout: %s' % lasso.strError(error[0]))
|
||||
return slo_return_response(logout)
|
||||
|
||||
logger.info('singleLogout: from %s' % logout.remoteProviderId)
|
||||
|
||||
policy = get_idp_options_policy(provider_loaded)
|
||||
if not policy:
|
||||
logger.error('singleLogout: No policy found for %s'\
|
||||
% logout.remoteProviderId)
|
||||
return return_logout_error(request, logout,
|
||||
AUTHENTIC_STATUS_CODE_UNAUTHORIZED)
|
||||
if not policy.accept_slo:
|
||||
logger.warn('singleLogout: received slo from %s not authorized'\
|
||||
% logout.remoteProviderId)
|
||||
return return_logout_error(request, logout,
|
||||
AUTHENTIC_STATUS_CODE_UNAUTHORIZED)
|
||||
|
||||
load_session(request, logout, kind=LIBERTY_SESSION_DUMP_KIND_SP)
|
||||
|
||||
try:
|
||||
logout.validateRequest()
|
||||
except lasso.Error, error:
|
||||
logger.error('singleLogout: %s' % lasso.strError(error[0]))
|
||||
return slo_return_response(logout)
|
||||
|
||||
#Play the role of IdP sending a SLO to all SP
|
||||
slo_soap_as_idp(request, logout)
|
||||
|
||||
#Break local session and respond to the IdP initiating the SLO
|
||||
if logout.isSessionDirty:
|
||||
if logout.session:
|
||||
save_session(request, logout, kind=LIBERTY_SESSION_DUMP_KIND_SP)
|
||||
else:
|
||||
delete_session(request)
|
||||
remove_liberty_session_sp(request)
|
||||
signals.auth_logout.send(sender=None, user=request.user)
|
||||
auth_logout(request)
|
||||
return slo_return_response(logout)
|
||||
|
||||
def metadata(self, env, values, request, response):
|
||||
title='metadata'
|
||||
|
|
Reference in New Issue