def sso_after_process_request(request, login, consent_obtained = True, user = None, save = True): '''Common path for sso and idp_initiated_sso. consent_obtained: whether the user has given his consent to this federation user: the user which must be federated, if None, current user is the default. save: whether to save the result of this transaction or not. ''' if user is None: user = request.user # Flags possible: # - consent # - isPassive # - forceAuthn # # 3. TODO: Check for permission if login.mustAuthenticate(): # TODO: # check that it exists a login transaction for this request id # - if there is, then provoke one with a redirect to # login?next=<current_url> # - if there is then set user_authenticated to the result of the # login event # Work around lack of informations returned by mustAuthenticate() if login.request.forceAuthn or request.user.is_anonymous(): return redirect_to_login(request.get_full_path()) else: user_authenticated = True else: user_authenticated = not request.user.is_anonymous() # 3.1 Ask for consent if user_authenticated: # TODO: for autoloaded providers always ask for consent if login.mustAskForConsent() or not consent_obtained: # TODO: replace False by check against request id if False: consent_obtained = True # i.e. redirect to /idp/consent?id=requestId # then check that Consent(id=requestId) exists in the database else: return HttpResponseRedirect('consent_federation?id=%s&next=%s' % ( login.request.requestId, urllib.quote(request.get_full_path())) ) # 4. Validate the request, passing authentication and consent status try: login.validateRequestMsg(user_authenticated, consent_obtained) except: raise do_federation = False else: do_federation = True # 5. Lookup the federations if do_federation: load_federation(request, login, user) load_session(request, login) # 3. Build and assertion, fill attributes build_assertion(request, login) return finish_sso(request, login, user = user, save = save)
def idp_sso(request, provider_id, user_id=None): '''Initiate an SSO toward provider_id without a prior AuthnRequest ''' assert provider_id, 'You must call idp_initiated_sso with a provider_id parameter' server = create_idff12_server(request, reverse(metadata)) login = lasso.Login(server) liberty_provider = load_provider(request, provider_id, server=login.server) service_provider = liberty_provider.service_provider binding = service_provider.prefered_assertion_consumer_binding nid_policy = service_provider.default_name_id_format if user_id: user = User.get(id=user_id) if not check_delegated_authentication_permission(request): logging.warning( 'ID-FFv1.2: %r tried to log as %r on %r but was forbidden' % (request.user, user, provider_id)) return HttpResponseForbidden( 'You must be superuser to log as another user') else: user = request.user load_federation(request, login, user) if not liberty_provider: message = _('ID-FFv1.2: provider %r unknown') % provider_id logging.warning('ID-FFv1.2: provider %r unknown' % provider_id) return HttpResponseForbidden(message) login.initIdpInitiatedAuthnRequest(provider_id) if binding == 'art': login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_ART elif binding == 'post': login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_POST else: raise Exception('Unsupported binding %r' % binding) if nid_policy == 'persistent': login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_FEDERATED elif nid_policy == 'transient': login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_ONE_TIME else: message = _( 'ID-FFv1.2: default nameIdPolicy unsupported %r') % nid_policy logging.error(message) raise Exception(message) login.processAuthnRequestMsg(None) return sso_after_process_request(request, login, consent_obtained=True, user=user, save=False)
def idp_sso(request, provider_id, user_id = None): '''Initiate an SSO toward provider_id without a prior AuthnRequest ''' assert provider_id, 'You must call idp_initiated_sso with a provider_id parameter' server = create_idff12_server(request, reverse(metadata)) login = lasso.Login(server) liberty_provider = load_provider(request, provider_id, server=login.server) service_provider = liberty_provider.service_provider binding = service_provider.prefered_assertion_consumer_binding nid_policy = service_provider.default_name_id_format if user_id: user = User.get(id = user_id) if not check_delegated_authentication_permission(request): logging.warning('ID-FFv1.2: %r tried to log as %r on %r but was forbidden' % ( request.user, user, provider_id)) return HttpResponseForbidden('You must be superuser to log as another user') else: user = request.user load_federation(request, login, user) if not liberty_provider: message = _('ID-FFv1.2: provider %r unknown') % provider_id logging.warning('ID-FFv1.2: provider %r unknown' % provider_id) return HttpResponseForbidden(message) login.initIdpInitiatedAuthnRequest(provider_id) if binding == 'art': login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_ART elif binding == 'post': login.request.protocolProfile = lasso.LIB_PROTOCOL_PROFILE_BRWS_POST else: raise Exception('Unsupported binding %r' % binding) if nid_policy == 'persistent': login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_FEDERATED elif nid_policy == 'transient': login.request.nameIdPolicy = lasso.LIB_NAMEID_POLICY_TYPE_ONE_TIME else: message = _('ID-FFv1.2: default nameIdPolicy unsupported %r') % nid_policy logging.error(message) raise Exception(message) login.processAuthnRequestMsg(None) return sso_after_process_request(request, login, consent_obtained = True, user = user, save = False)
def sso_after_process_request(request, login, consent_obtained=True, user=None, save=True): '''Common path for sso and idp_initiated_sso. consent_obtained: whether the user has given his consent to this federation user: the user which must be federated, if None, current user is the default. save: whether to save the result of this transaction or not. ''' if user is None: user = request.user # Flags possible: # - consent # - isPassive # - forceAuthn # # 3. TODO: Check for permission if login.mustAuthenticate(): # TODO: # check that it exists a login transaction for this request id # - if there is, then provoke one with a redirect to # login?next=<current_url> # - if there is then set user_authenticated to the result of the # login event # Work around lack of informations returned by mustAuthenticate() if login.request.forceAuthn or request.user.is_anonymous(): return redirect_to_login(request.get_full_path()) else: user_authenticated = True else: user_authenticated = not request.user.is_anonymous() # 3.1 Ask for consent if user_authenticated: # TODO: for autoloaded providers always ask for consent if login.mustAskForConsent() or not consent_obtained: # TODO: replace False by check against request id if False: consent_obtained = True # i.e. redirect to /idp/consent?id=requestId # then check that Consent(id=requestId) exists in the database else: return HttpResponseRedirect( 'consent_federation?id=%s&next=%s' % (login.request.requestId, urllib.quote(request.get_full_path()))) # 4. Validate the request, passing authentication and consent status try: login.validateRequestMsg(user_authenticated, consent_obtained) except: raise do_federation = False else: do_federation = True # 5. Lookup the federations if do_federation: load_federation(request, login, user) load_session(request, login) # 3. Build and assertion, fill attributes build_assertion(request, login) return finish_sso(request, login, user=user, save=save)