def do_auth(self, areq, redirect_uri, cinfo, request, cookie, **kwargs): """ :param areq: :param redirect_uri: :param cinfo: :param request: :param cookie: :param authn: :param kwargs: :return: """ acrs = self._acr_claims(areq) if acrs: # If acr claims are present the picked acr value MUST match # one of the given tup = (None, None) for acr in acrs: res = self.authn_broker.pick(acr, "exact") logger.debug("Picked AuthN broker for ACR %s: %s" % ( str(acr), str(res))) if res: # Return the best guess by pick. tup = res[0] break authn, authn_class_ref = tup else: authn, authn_class_ref = self.pick_auth(areq) if not authn: authn, authn_class_ref = self.pick_auth(areq, "better") if not authn: authn, authn_class_ref = self.pick_auth(areq, "any") if authn is None: return redirect_authz_error("access_denied", redirect_uri, return_type=areq["response_type"]) try: try: _auth_info = kwargs["authn"] except KeyError: _auth_info = "" if "upm_answer" in areq and areq["upm_answer"] == "true": _max_age = 0 else: _max_age = max_age(areq) identity, _ts = authn.authenticated_as( cookie, authorization=_auth_info, max_age=_max_age) except (NoSuchAuthentication, TamperAllert): identity = None _ts = 0 except ToOld: logger.info("Too old authentication") identity = None _ts = 0 else: logger.info("No active authentication") # gather information to be used by the authentication method authn_args = {"authn_class_ref": authn_class_ref} # Can't be something like JSON because it can't contain '"' if isinstance(request, Message): authn_args["query"] = request.to_urlencoded() elif isinstance(request, dict): authn_args["query"] = Message(**request).to_urlencoded() else: authn_args["query"] = request if "req_user" in kwargs: authn_args["as_user"] = kwargs["req_user"], for attr in ["policy_uri", "logo_uri", "tos_uri"]: try: authn_args[attr] = cinfo[attr] except KeyError: pass for attr in ["ui_locales", "acr_values"]: try: authn_args[attr] = areq[attr] except KeyError: pass # To authenticate or Not if identity is None: # No! if "prompt" in areq and "none" in areq["prompt"]: # Need to authenticate but not allowed return redirect_authz_error( "login_required", redirect_uri, return_type=areq["response_type"]) else: return authn(**authn_args) else: if re_authenticate(areq, authn): # demand re-authentication return authn(**authn_args) else: # I get back a dictionary user = identity["uid"] if "req_user" in kwargs: sids_for_sub = self.sdb.get_sids_by_sub(kwargs["req_user"]) if sids_for_sub and user != \ self.sdb.get_authentication_event( sids_for_sub[-1]).uid: logger.debug("Wanted to be someone else!") if "prompt" in areq and "none" in areq["prompt"]: # Need to authenticate but not allowed return redirect_authz_error("login_required", redirect_uri) else: return authn(**authn_args) authn_event = AuthnEvent(identity["uid"], identity.get('salt', ''), authn_info=authn_class_ref, time_stamp=_ts) return {"authn_event": authn_event, "identity": identity, "user": user}
def auth_init(self, request, request_class=AuthorizationRequest): """ :param request: The AuthorizationRequest :return: """ logger.debug("Request: '%s'" % sanitize(request)) # Same serialization used for GET and POST try: areq = self.server.parse_authorization_request( request=request_class, query=request) except (MissingRequiredValue, MissingRequiredAttribute, AuthzError) as err: logger.debug("%s" % err) areq = request_class() areq.lax = True if isinstance(request, dict): areq.from_dict(request) else: areq.deserialize(request, "urlencoded") try: redirect_uri = self.get_redirect_uri(areq) except (RedirectURIError, ParameterError, UnknownClient) as err: return error_response("invalid_request", "%s" % err) try: _rtype = areq["response_type"] except KeyError: _rtype = ["code"] try: _state = areq["state"] except KeyError: _state = '' return redirect_authz_error("invalid_request", redirect_uri, "%s" % err, _state, _rtype) except KeyError: areq = request_class().deserialize(request, "urlencoded") # verify the redirect_uri try: self.get_redirect_uri(areq) except (RedirectURIError, ParameterError) as err: return error_response("invalid_request", "%s" % err) except Exception as err: message = traceback.format_exception(*sys.exc_info()) logger.error(message) logger.debug("Bad request: %s (%s)" % (err, err.__class__.__name__)) err = ErrorResponse(error='invalid_request', error_description=str(err)) return BadRequest(err.to_json(), content='application/json') if not areq: logger.debug("No AuthzRequest") return error_response("invalid_request", "Can not parse AuthzRequest") areq = self.filter_request(areq) if self.events: self.events.store('Protocol request', areq) try: _cinfo = self.cdb[areq['client_id']] except KeyError: logger.error( 'Client ID ({}) not in client database'.format( areq['client_id'])) return error_response('unauthorized_client', 'unknown client') else: try: _registered = [set(rt.split(' ')) for rt in _cinfo['response_types']] except KeyError: # If no response_type is registered by the client then we'll # code which it the default according to the OIDC spec. _registered = [{'code'}] _wanted = set(areq["response_type"]) if _wanted not in _registered: return error_response("invalid_request", "Trying to use unregistered response_typ") logger.debug("AuthzRequest: %s" % (sanitize(areq.to_dict()),)) try: redirect_uri = self.get_redirect_uri(areq) except (RedirectURIError, ParameterError, UnknownClient) as err: return error_response("invalid_request", "{}:{}".format(err.__class__.__name__, err)) try: keyjar = self.keyjar except AttributeError: keyjar = "" try: # verify that the request message is correct areq.verify(keyjar=keyjar, opponent_id=areq["client_id"]) except (MissingRequiredAttribute, ValueError, MissingRequiredValue) as err: return redirect_authz_error("invalid_request", redirect_uri, "%s" % err) return {"areq": areq, "redirect_uri": redirect_uri}