コード例 #1
0
    def password_grant_type(self, areq):
        """
        Token authorization using Resource owner password credentials.

        RFC6749 section 4.3
        """
        # `Any` comparison tries a first broker, so we either hit an IndexError or get a method
        try:
            authn, authn_class_ref = self.pick_auth(areq, "any")
        except IndexError:
            err = TokenErrorResponse(error="invalid_grant")
            return Unauthorized(err.to_json(), content="application/json")
        identity, _ts = authn.authenticated_as(
            username=areq["username"], password=areq["password"]
        )
        if identity is None:
            err = TokenErrorResponse(error="invalid_grant")
            return Unauthorized(err.to_json(), content="application/json")
        # We are returning a token
        areq["response_type"] = ["token"]
        authn_event = AuthnEvent(
            identity["uid"],
            identity.get("salt", ""),
            authn_info=authn_class_ref,
            time_stamp=_ts,
        )
        sid = self.setup_session(areq, authn_event, self.cdb[areq["client_id"]])
        _at = self.sdb.upgrade_to_token(self.sdb[sid]["code"], issue_refresh=True)
        atr_class = self.server.message_factory.get_response_type("token_endpoint")
        atr = atr_class(**by_schema(atr_class, **_at))
        return Response(
            atr.to_json(), content="application/json", headers=OAUTH2_NOCACHE_HEADERS
        )
コード例 #2
0
    def verify(self, request, **kwargs):
        """
        Verifies that the given totp was correct
        :param request: Either the query part of a URL a urlencoded
        body of a HTTP message or a parse such.
        :param kwargs: Catch whatever else is sent.
        :return: redirect back to where ever the base applications
        wants the user after authentication.
        """
        if isinstance(request, six.string_types):
            _dict = parse_qs(request)
        elif isinstance(request, dict):
            _dict = request
        else:
            raise ValueError("Wrong type of input")

        # verify totp
        try:
            # Do verification
            totp_generator = pyotp.TOTP(self.get_totp_secret_key(_dict["username"][0]))
            assert (True == totp_generator.verify(_dict["totp"][0]))
        except (AssertionError, KeyError):
            resp = Unauthorized("Wrong TOTP")
            ##resp = Unauthorized("Unknown user or wrong password")

            kwargs["request"] = request
            kwargs["form_action"] = kwargs["url"]
            argv = self.templ_arg_func(0, **kwargs)
            argv['wrong_value'] = 1
            argv['form_action'] = kwargs["baseurl"] + "/totp_login"
            argv['username'] = _dict['username'][0]
            argv['acr'] = argv['form_action']
            argv['title'] = 'TOTP verification'

            self.nerror = self.nerror + 1
            if (self.nerror>=3):
                self.nerror = 0
                argv['wrong_value'] = 4

            mte = self.template_lookup.get_template('totp_form.mako')
            resp.message = mte.render(**argv).decode("utf-8")
            return resp, False

        else:
            # If I remove this header, authentication enters in a infinite loop.
            headers = [self.create_cookie(_dict["username"][0], "upm")]
            try:
                _qp = _dict["query"][0]
            except KeyError:
                _qp = self.get_multi_auth_cookie(kwargs['cookie'])
            try:
                return_to = self.generate_return_url(kwargs["return_to"], _qp)
            except KeyError:
                try:
                    return_to = self.generate_return_url(self.return_to, _qp,
                                                         kwargs["path"])
                except KeyError:
                    return_to = self.generate_return_url(self.return_to, _qp)

            return SeeOther(return_to, headers=headers), True
コード例 #3
0
    def client_info_endpoint(self, method="GET", **kwargs):
        """
        Operations on this endpoint are switched through the use of different HTTP methods.

        :param method: HTTP method used for the request
        :param kwargs: keyword arguments
        :return: A Response instance
        """
        _query = compact(parse_qs(kwargs["query"]))
        try:
            _id = _query["client_id"]
        except KeyError:
            return BadRequest("Missing query component")

        if _id not in self.cdb:
            return Unauthorized()

        # authenticated client
        try:
            self.verify_client(
                kwargs["environ"], kwargs["request"], "bearer_header", client_id=_id
            )
        except (AuthnFailure, UnknownAssertionType):
            return Unauthorized()

        if method == "GET":
            return self.client_info(_id)
        elif method == "PUT":
            try:
                _request = self.server.message_factory.get_request_type(
                    "update_endpoint"
                )().from_json(kwargs["request"])
            except ValueError as err:
                return BadRequest(str(err))

            try:
                _request.verify()
            except InvalidRedirectUri as err:
                msg = ClientRegistrationError(
                    error="invalid_redirect_uri", error_description="%s" % err
                )
                return BadRequest(msg.to_json(), content="application/json")
            except (MissingPage, VerificationError) as err:
                msg = ClientRegistrationError(
                    error="invalid_client_metadata", error_description="%s" % err
                )
                return BadRequest(msg.to_json(), content="application/json")

            try:
                self.client_info_update(_id, _request)
                return self.client_info(_id)
            except ModificationForbidden:
                return Forbidden()
        elif method == "DELETE":
            try:
                del self.cdb[_id]
            except KeyError:
                return Unauthorized()
            else:
                return NoContent()
コード例 #4
0
    def verify(self, request, **kwargs):
        """
        Verifies that the given username and password was correct
        :param request: Either the query part of a URL a urlencoded
        body of a HTTP message or a parse such.
        :param kwargs: Catch whatever else is sent.
        :return: redirect back to where ever the base applications
        wants the user after authentication.
        """

        logger.debug("verify(%s)" % sanitize(request))
        if isinstance(request, six.string_types):
            _dict = compact(parse_qs(request))
        elif isinstance(request, dict):
            _dict = request
        else:
            raise ValueError("Wrong type of input")

        logger.debug("dict: %s" % sanitize(_dict))
        # verify username and password
        try:
            self._verify(_dict["password"], _dict["login"])  # dict origin
        except TypeError:
            try:
                self._verify(_dict["password"][0], _dict["login"][0])
            except (AssertionError, KeyError) as err:
                logger.debug("Password verification failed: {}".format(err))
                resp = Unauthorized("Unknown user or wrong password")
                return resp, False
            else:
                try:
                    _qp = _dict["query"]
                except KeyError:
                    _qp = self.get_multi_auth_cookie(kwargs['cookie'])
        except (AssertionError, KeyError) as err:
            logger.debug("Password verification failed: {}".format(err))
            resp = Unauthorized("Unknown user or wrong password")
            return resp, False
        else:
            try:
                _qp = _dict["query"]
            except KeyError:
                _qp = self.get_multi_auth_cookie(kwargs['cookie'])

        logger.debug("Password verification succeeded.")
        # if "cookie" not in kwargs or self.srv.cookie_name not in kwargs["cookie"]:
        headers = [self.create_cookie(_dict["login"], "upm")]
        try:
            return_to = self.generate_return_url(kwargs["return_to"], _qp)
        except KeyError:
            try:
                return_to = self.generate_return_url(self.return_to, _qp,
                                                     kwargs["path"])
            except KeyError:
                return_to = self.generate_return_url(self.return_to, _qp)

        return SeeOther(return_to, headers=headers), True
コード例 #5
0
ファイル: dynreg.py プロジェクト: programDEV/pyoidc
    def client_info_endpoint(self,
                             request,
                             environ,
                             method="GET",
                             query="",
                             **kwargs):
        """
        Operations on this endpoint are switched through the use of different
        HTTP methods

        :param request: The request
        :param authn: Client authentication information
        :param method: HTTP method used for the request
        :param query: The query part of the URL used, this is where the
            client_id is supposed to reside.
        :param kwargs: extra keyword arguments
        :return: A Response instance
        """

        _query = urlparse.parse_qs(query)
        try:
            _id = _query["client_id"][0]
        except KeyError:
            return BadRequest("Missing query component")

        try:
            assert _id in self.cdb
        except AssertionError:
            return Unauthorized()

        # authenticated client
        try:
            _ = self.verify_client(environ,
                                   request,
                                   "bearer_header",
                                   client_id=_id)
        except (AuthnFailure, UnknownAssertionType):
            return Unauthorized()

        if method == "GET":
            return self.client_info(_id)
        elif method == "PUT":
            try:
                _request = ClientUpdateRequest().from_json(request)
            except ValueError:
                return BadRequest()

            try:
                _request.verify()
            except InvalidRedirectUri, err:
                msg = ClientRegistrationError(error="invalid_redirect_uri",
                                              error_description="%s" % err)
                return BadRequest(msg.to_json(), content="application/json")
            except (MissingPage, VerificationError), err:
                msg = ClientRegistrationError(error="invalid_client_metadata",
                                              error_description="%s" % err)
                return BadRequest(msg.to_json(), content="application/json")
コード例 #6
0
ファイル: user_cas.py プロジェクト: zizhang-wish/pyoidc
    def verify(self, request, cookie, **kwargs):
        """
        Verify if the authentication was successful.

        :rtype : Response
        :param request: Contains the request parameters.
        :param cookie: Cookies sent with the request.
        :param kwargs: Any other parameters.
        :return: If the authentication was successful: a redirect to the
        return_to url. Otherwise a unauthorized response.
        :raise: ValueError
        """
        logger.debug("verify(%s)" % request)
        if isinstance(request, str):
            _dict = parse_qs(request)
        elif isinstance(request, dict):
            _dict = request
        else:
            raise ValueError("Wrong type of input")
        try:
            cas_cookie, _ts, _typ = self.getCookieValue(
                cookie, self.CONST_CAS_COOKIE)
            data = json.loads(cas_cookie)
            nonce = base64.b64decode(data[self.CONST_NONCE])
            if nonce != _dict[self.CONST_NONCE][0]:
                logger.warning(
                    "Someone tried to login without a correct nonce!")
                return Unauthorized("You are not authorized!")
            acr = None
            try:
                acr = _dict["acr_values"][0]
            except KeyError:
                pass
            uid = self.handle_callback(_dict[self.CONST_TICKET],
                                       self.get_service_url(nonce, acr))
            if uid is None or uid == "":
                logger.info("Someone tried to login, but was denied by CAS!")
                return Unauthorized("You are not authorized!")
            cookie = self.create_cookie(uid, "casm")
            return_to = self.generate_return_url(self.return_to, uid)
            if "?" in return_to:
                return_to += "&"
            else:
                return_to += "?"
            return_to += base64.b64decode(data[self.CONST_QUERY])
            return SeeOther(return_to, headers=[cookie])
        except Exception:
            # FIXME: This should catch specific exception thrown from methods in the block
            logger.critical(
                "Metod verify in user_cas.py had a fatal exception.",
                exc_info=True)
            return Unauthorized("You are not authorized!")
コード例 #7
0
    def code_grant_type(self, areq):
        # assert that the code is valid
        try:
            _info = self.sdb[areq["code"]]
        except KeyError:
            err = TokenErrorResponse(error="invalid_grant",
                                     error_description="Unknown access grant")
            return Response(err.to_json(),
                            content="application/json",
                            status="401 Unauthorized")

        authzreq = json.loads(_info['authzreq'])
        if 'code_verifier' in areq:
            try:
                _method = authzreq['code_challenge_method']
            except KeyError:
                _method = 'S256'

            resp = self.verify_code_challenge(areq['code_verifier'],
                                              authzreq['code_challenge'],
                                              _method)
            if resp:
                return resp

        if 'state' in areq:
            if self.sdb[areq['code']]['state'] != areq['state']:
                err = TokenErrorResponse(error="unauthorized_client")
                return Unauthorized(err.to_json(), content="application/json")

        resp = self.token_scope_check(areq, _info)
        if resp:
            return resp

        # If redirect_uri was in the initial authorization request
        # verify that the one given here is the correct one.
        if "redirect_uri" in _info:
            assert areq["redirect_uri"] == _info["redirect_uri"]

        issue_refresh = False
        if 'scope' in authzreq and 'offline_access' in authzreq['scope']:
            if authzreq['response_type'] == 'code':
                issue_refresh = True

        try:
            _tinfo = self.sdb.upgrade_to_token(areq["code"],
                                               issue_refresh=issue_refresh)
        except AccessCodeUsed:
            err = TokenErrorResponse(error="invalid_grant",
                                     error_description="Access grant used")
            return Response(err.to_json(),
                            content="application/json",
                            status="401 Unauthorized")

        logger.debug("_tinfo: %s" % _tinfo)

        atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo))

        logger.debug("AccessTokenResponse: %s" % atr)

        return Response(atr.to_json(), content="application/json")
コード例 #8
0
ファイル: authzsrv.py プロジェクト: simudream/pyuma
 def introspection_endpoint(self, request="", **kwargs):
     try:
         entity, client_id = client_authentication(self.sdb,
                                                   kwargs["authn"])
     except AuthnFailed:
         return Unauthorized()
     return self.introspection_endpoint_(request, entity, **kwargs)
コード例 #9
0
ファイル: dynreg.py プロジェクト: atidev/pyoidc
    def registration_endpoint(self, request, environ, **kwargs):
        """

        :param request: The request
        :param authn: Client authentication information
        :param kwargs: extra keyword arguments
        :return: A Response instance
        """

        _request = RegistrationRequest().deserialize(request, "json")
        try:
            _request.verify()
        except InvalidRedirectUri as err:
            msg = ClientRegistrationError(error="invalid_redirect_uri",
                                          error_description="%s" % err)
            return BadRequest(msg.to_json(), content="application/json")
        except (MissingPage, VerificationError) as err:
            msg = ClientRegistrationError(error="invalid_client_metadata",
                                          error_description="%s" % err)
            return BadRequest(msg.to_json(), content="application/json")

        # authenticated client
        if self.authn_at_registration:
            try:
                _ = self.verify_client(environ, _request,
                                       self.authn_at_registration)
            except (AuthnFailure, UnknownAssertionType):
                return Unauthorized()

        client_id = self.create_new_client(_request)

        return self.client_info(client_id)
コード例 #10
0
ファイル: as.py プロジェクト: simudream/pyuma
def authn(environ, session):

    # verify the username+password
    if environ["REQUEST_METHOD"] == "POST":
        query = parse_qs(get_body(environ))
    else:  # Assume environ["REQUEST_METHOD"] == "GET"
        query = parse_qs(environ["QUERY_STRING"])

    try:
        assert uma_as.PASSWD[query["login"][0]] == query["password"][0]
    except (KeyError, AssertionError):
        return Unauthorized(), {}

    #uid = uma_as.UID2EPPN[query["login"][0]]
    uid = query["login"][0]
    cval = {"user": uid, "authn": PASSWORD}
    headers = [
        CookieHandler.create_cookie("%s" % (cval, ), "sso", COOKIE_NAME)
    ]

    session["user"] = uid
    try:
        op = query["operation"][0]
        if op == "chose_permissions":
            return chose_permissions(environ, session)
        elif op == "set_permission":
            return set_permission(environ, session)
        elif op == "manage":
            return manage(uid, headers)
        else:
            pass
    except KeyError:
        pass

    return Response(), {}
コード例 #11
0
ファイル: endpoints.py プロジェクト: selfissued/oidctest
def safe(environ, start_response):
    _op = environ["oic.oas"]
    _srv = _op.server
    _log_info = _op.logger.info

    _log_info("- safe -")
    # _log_info("env: %s" % environ)
    # _log_info("handle: %s" % (handle,))

    try:
        _authz = environ["HTTP_AUTHORIZATION"]
        (_typ, code) = _authz.split(" ")
        assert _typ == "Bearer"
    except KeyError:
        resp = BadRequest("Missing authorization information")
        return resp(environ, start_response)

    try:
        _sinfo = _srv.sdb[code]
    except KeyError:
        resp = Unauthorized("Not authorized")
        return resp(environ, start_response)

    _info = "'%s' secrets" % _sinfo["sub"]
    resp = Response(_info)
    return resp(environ, start_response)
コード例 #12
0
        def verify(self, request, cookie, path, requrl, **kwargs):
            """
            Verifies if the authentication was successful.

            :rtype : Response
            :param request: Contains the request parameters.
            :param cookie: Cookies sent with the request.
            :param kwargs: Any other parameters.
            :return: If the authentication was successful: a redirect to the
            return_to url. Otherwise a unauthorized response.
            :raise: ValueError
            """
            binding = None
            if path == "/" + self.sp_conf.ASCPOST:
                binding = BINDING_HTTP_POST
            if path == "/" + self.sp_conf.ASCREDIRECT:
                binding = BINDING_HTTP_REDIRECT

            saml_cookie, _ts, _typ = self.getCookieValue(
                cookie, self.CONST_SAML_COOKIE)
            data = json.loads(saml_cookie)

            if data[self.CONST_HASIDP] == 'False':
                (done, response) = self._pick_idp(request)
                if done == 0:
                    entity_id = response
                    # Do the AuthnRequest
                    resp = self._redirect_to_auth(
                        self.sp, entity_id,
                        base64.b64decode(data[self.CONST_QUERY]))
                    return resp
                return response

            if not request:
                logger.info("Missing Response")
                return Unauthorized("You are not authorized!")

            try:
                response = self.sp.parse_authn_request_response(
                    request["SAMLResponse"][0], binding,
                    self.cache_outstanding_queries)
            except UnknownPrincipal, excp:
                logger.error("UnknownPrincipal: %s" % (excp, ))
                return Unauthorized(self.not_authorized)
コード例 #13
0
    def token_endpoint(self, authn="", **kwargs):
        """
        This is where clients come to get their access tokens
        """

        _sdb = self.sdb

        logger.debug("- token -")
        body = kwargs["request"]
        logger.debug("body: %s" % sanitize(body))

        areq = AccessTokenRequest().deserialize(body, "urlencoded")

        try:
            self.client_authn(self, areq, authn)
        except FailedAuthentication as err:
            logger.error(err)
            err = TokenErrorResponse(error="unauthorized_client",
                                     error_description="%s" % err)
            return Response(err.to_json(), content="application/json", status_code=401)

        logger.debug("AccessTokenRequest: %s" % sanitize(areq))

        if areq["grant_type"] != "authorization_code":
            err = TokenErrorResponse(error="invalid_request", error_description="Wrong grant type")
            return Response(err.to_json(), content="application/json", status="401 Unauthorized")

        # assert that the code is valid
        _info = _sdb[areq["code"]]

        resp = self.token_scope_check(areq, _info)
        if resp:
            return resp

        # If redirect_uri was in the initial authorization request
        # verify that the one given here is the correct one.
        if "redirect_uri" in _info and areq["redirect_uri"] != _info["redirect_uri"]:
            logger.error('Redirect_uri mismatch')
            err = TokenErrorResponse(error="unauthorized_client")
            return Unauthorized(err.to_json(), content="application/json")

        try:
            _tinfo = _sdb.upgrade_to_token(areq["code"], issue_refresh=True)
        except AccessCodeUsed:
            err = TokenErrorResponse(error="invalid_grant",
                                     error_description="Access grant used")
            return Response(err.to_json(), content="application/json",
                            status="401 Unauthorized")

        logger.debug("_tinfo: %s" % sanitize(_tinfo))

        atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo))

        logger.debug("AccessTokenResponse: %s" % sanitize(atr))

        return Response(atr.to_json(), content="application/json", headers=OAUTH2_NOCACHE_HEADERS)
コード例 #14
0
    def rpt_endpoint(self, authn, **kwargs):
        """
        :param authn: authentication information
        """
        try:
            entity, client_id = client_authentication(self.sdb, authn)
        except AuthnFailed:
            return Unauthorized()

        return self.rpt_endpoint_(entity, client_id, **kwargs)
コード例 #15
0
    def permission_registration_endpoint(self, request="", authn="", **kwargs):
        try:
            entity, client_id = client_authentication(self.sdb, authn)
        except AuthnFailed:
            return Unauthorized()

        return self.permission_registration_endpoint_(owner=entity,
                                                      request=request,
                                                      client_id=client_id,
                                                      **kwargs)
コード例 #16
0
    def registration_endpoint(self, **kwargs):
        """
        Perform dynamic client registration.

        :param request: The request
        :param authn: Client authentication information
        :param kwargs: extra keyword arguments
        :return: A Response instance
        """
        _request = self.server.message_factory.get_request_type(
            "registration_endpoint"
        )().deserialize(kwargs["request"], "json")
        try:
            _request.verify(keyjar=self.keyjar)
        except InvalidRedirectUri as err:
            msg = ClientRegistrationError(
                error="invalid_redirect_uri", error_description="%s" % err
            )
            return BadRequest(msg.to_json(), content="application/json")
        except (MissingPage, VerificationError) as err:
            msg = ClientRegistrationError(
                error="invalid_client_metadata", error_description="%s" % err
            )
            return BadRequest(msg.to_json(), content="application/json")

        # If authentication is necessary at registration
        if self.authn_at_registration:
            try:
                self.verify_client(
                    kwargs["environ"], _request, self.authn_at_registration
                )
            except (AuthnFailure, UnknownAssertionType):
                return Unauthorized()

        client_restrictions = {}  # type: ignore
        if "parsed_software_statement" in _request:
            for ss in _request["parsed_software_statement"]:
                client_restrictions.update(self.consume_software_statement(ss))
            del _request["software_statement"]
            del _request["parsed_software_statement"]

        try:
            client_id = self.create_new_client(_request, client_restrictions)
        except CapabilitiesMisMatch as err:
            msg = ClientRegistrationError(
                error="invalid_client_metadata", error_description="%s" % err
            )
            return BadRequest(msg.to_json(), content="application/json")
        except RestrictionError as err:
            msg = ClientRegistrationError(
                error="invalid_client_metadata", error_description="%s" % err
            )
            return BadRequest(msg.to_json(), content="application/json")

        return self.client_info(client_id)
コード例 #17
0
def authenticated_call(sdb, func, authn, request=None, **kwargs):
    try:
        entity, client_id = client_authentication(sdb, authn)
    except AuthnFailed:
        return Unauthorized()
    else:
        kwargs["entity"] = entity
        kwargs["client_id"] = client_id
        if request:
            kwargs["request"] = request
    return func(**kwargs)
コード例 #18
0
ファイル: authzsrv.py プロジェクト: simudream/pyuma
 def resource_set_registration_endpoint(self,
                                        path,
                                        method,
                                        body="",
                                        if_match="",
                                        **kwargs):
     try:
         entity, client_id = client_authentication(self.sdb,
                                                   kwargs["authn"])
     except AuthnFailed:
         return Unauthorized()
     return self.resource_set_registration_endpoint_(
         entity, path, method, client_id, body, if_match, **kwargs)
コード例 #19
0
    def verify(self, request, **kwargs):
        """
        Verifies that the given username and password was correct
        :param request: Either the query part of a URL a urlencoded
        body of a HTTP message or a parse such.
        :param kwargs: Catch whatever else is sent.
        :return: redirect back to where ever the base applications
        wants the user after authentication.
        """

        logger.debug("verify(%s)" % request)
        if isinstance(request, basestring):
            _dict = parse_qs(request)
        elif isinstance(request, dict):
            _dict = request
        else:
            raise ValueError("Wrong type of input")

        logger.debug("dict: %s" % _dict)
        logger.debug("passwd: %s" % self.passwd)
        # verify username and password
        try:
            self._verify(_dict["password"][0], _dict["login"][0])
        except (AssertionError, KeyError):
            resp = Unauthorized("Unknown user or wrong password")
            return resp, False
        else:
            cookie = self.create_cookie(_dict["login"][0], "upm")
            try:
                _qp = _dict["query"][0]
            except KeyError:
                _qp = self.get_multi_auth_cookie(kwargs['cookie'])
            try:
                return_to = self.generate_return_url(kwargs["return_to"], _qp)
            except KeyError:
                try:
                    return_to = self.generate_return_url(
                        self.return_to, _qp, kwargs["path"])
                except KeyError:
                    return_to = self.generate_return_url(self.return_to, _qp)

            return Redirect(return_to, headers=[cookie]), True
コード例 #20
0
ファイル: javascript_login.py プロジェクト: tingletech/pyoidc
    def verify(self, request, **kwargs):
        """
        Verifies that the given username and password was correct
        :param request: Either the query part of a URL a urlencoded
        body of a HTTP message or a parse such.
        :param kwargs: Catch whatever else is sent.
        :return: redirect back to where ever the base applications
        wants the user after authentication.
        """

        logger.debug("verify(%s)" % request)
        if isinstance(request, six.string_types):
            _dict = parse_qs(request)
        elif isinstance(request, dict):
            _dict = request
        else:
            raise ValueError("Wrong type of input")

        logger.debug("dict: %s" % _dict)
        logger.debug("passwd: %s" % self.passwd)
        # verify username and password
        try:
            assert _dict['login_parameter'][0] == 'logged_in'
        except (AssertionError, KeyError):
            resp = Unauthorized(
                "You are not authorized. Javascript not executed")
            return resp, False
        else:
            cookie = self.create_cookie("diana", "upm")
            try:
                _qp = _dict["query"][0]
            except KeyError:
                _qp = self.get_multi_auth_cookie(kwargs['cookie'])
            try:
                return_to = self.generate_return_url(kwargs["return_to"], _qp)
            except KeyError:
                return_to = self.generate_return_url(self.return_to, _qp)
            resp = SeeOther(return_to, headers=[cookie])

        return resp, True
コード例 #21
0
ファイル: provider.py プロジェクト: zack53/pyoidc
    def code_grant_type(self, areq):
        """
        Token authorization using Code Grant.

        RFC6749 section 4.1
        """
        try:
            _tinfo = self.sdb.upgrade_to_token(areq["code"],
                                               issue_refresh=True)
        except AccessCodeUsed:
            error = TokenErrorResponse(error="invalid_grant",
                                       error_description="Access grant used")
            return Unauthorized(error.to_json(), content="application/json")

        logger.debug("_tinfo: %s" % sanitize(_tinfo))

        atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo))

        logger.debug("AccessTokenResponse: %s" % sanitize(atr))

        return Response(atr.to_json(),
                        content="application/json",
                        headers=OAUTH2_NOCACHE_HEADERS)
コード例 #22
0
ファイル: dynreg.py プロジェクト: programDEV/pyoidc
        except InvalidRedirectUri, err:
            msg = ClientRegistrationError(error="invalid_redirect_uri",
                                          error_description="%s" % err)
            return BadRequest(msg.to_json(), content="application/json")
        except (MissingPage, VerificationError), err:
            msg = ClientRegistrationError(error="invalid_client_metadata",
                                          error_description="%s" % err)
            return BadRequest(msg.to_json(), content="application/json")

        # authenticated client
        if self.authn_at_registration:
            try:
                _ = self.verify_client(environ, _request,
                                       self.authn_at_registration)
            except (AuthnFailure, UnknownAssertionType):
                return Unauthorized()

        client_id = self.create_new_client(_request)

        return self.client_info(client_id)

    def client_info_endpoint(self,
                             request,
                             environ,
                             method="GET",
                             query="",
                             **kwargs):
        """
        Operations on this endpoint are switched through the use of different
        HTTP methods
コード例 #23
0
        def verify(self,
                   request,
                   cookie,
                   path,
                   requrl,
                   end_point_index=None,
                   **kwargs):
            """
            Verifies if the authentication was successful.

            :rtype : Response
            :param request: Contains the request parameters.
            :param cookie: Cookies sent with the request.
            :param kwargs: Any other parameters.
            :return: If the authentication was successful: a redirect to the
            return_to url. Otherwise a unauthorized response.
            :raise: ValueError
            """
            if isinstance(request, basestring):
                request = parse_qs(request)
            elif isinstance(request, dict):
                pass
            else:
                raise ValueError("Wrong type of input")

            acs = self.sp.config.getattr("endpoints",
                                         "sp")["assertion_consumer_service"]
            acs_endpoints = [(ep[0].rsplit("/", 1)[1], ep[1]) for ep in acs]
            binding = None
            path = path[1:]
            for endp in acs_endpoints:
                if path == endp[0]:
                    binding = endp[1]
                    break

            saml_cookie, _ts, _typ = self.getCookieValue(
                cookie, self.CONST_SAML_COOKIE)
            data = json.loads(saml_cookie)

            rp_query_cookie = self.get_multi_auth_cookie(cookie)

            query = rp_query_cookie

            if not query:
                query = base64.b64decode(data[self.CONST_QUERY])

            if data[self.CONST_HASIDP] == 'False':
                (done, response) = self._pick_idp(request, end_point_index)
                if done == 0:
                    entity_id = response
                    # Do the AuthnRequest
                    resp = self._redirect_to_auth(self.sp, entity_id, query,
                                                  end_point_index)
                    return resp, False
                return response, False

            if not request:
                logger.info("Missing Response")
                return Unauthorized("You are not authorized!"), False

            try:
                response = self.sp.parse_authn_request_response(
                    request["SAMLResponse"][0], binding,
                    self.cache_outstanding_queries)
            except UnknownPrincipal, excp:
                logger.error("UnknownPrincipal: %s" % (excp, ))
                return Unauthorized(self.not_authorized), False
コード例 #24
0
ファイル: saml.py プロジェクト: devel-linotp/pyoidc
        if not request:
            logger.info("Missing Response")
            return Unauthorized("You are not authorized!")

        try:
            response = self.sp.parse_authn_request_response(request["SAMLResponse"][0], binding,
                                                            self.cache_outstanding_queries)
        except UnknownPrincipal, excp:
            logger.error("UnknownPrincipal: %s" % (excp,))
            return Unauthorized(self.not_authorized)
        except UnsupportedBinding, excp:
            logger.error("UnsupportedBinding: %s" % (excp,))
            return Unauthorized(self.not_authorized)
        except VerificationError, err:
            logger.error("Verification error: %s" % (err,))
            return Unauthorized(self.not_authorized)
        except Exception, err:
            logger.error("Other error: %s" % (err,))
            return Unauthorized(self.not_authorized)

        if self.sp_conf.VALID_ATTRIBUTE_RESPONSE is not None:
            for k, v in self.sp_conf.VALID_ATTRIBUTE_RESPONSE.iteritems():
                if k not in response.ava:
                    return Unauthorized(self.not_authorized)
                else:
                    allowed = False
                    for allowed_attr_value in v:
                        if allowed_attr_value == response.ava[k] or allowed_attr_value in response.ava[k]:
                            allowed = True
                            break
                    if not allowed:
コード例 #25
0
ファイル: saml.py プロジェクト: devel-linotp/pyoidc
class SAMLAuthnMethod(UserAuthnMethod):
    CONST_QUERY = "query"
    CONST_SAML_COOKIE = "samlauthc"
    CONST_HASIDP = "hasidp"

    def __init__(self, srv, lookup, userdb, spconf, url, return_to, verification_endpoint="verify", cache=None, bindings=None):
        """
        Constructor for the class.
        :param srv: Usually none, but otherwise the oic server.
        :param return_to: The URL to return to after a successful
        authentication.
        """
        self.userdb = userdb
        if cache is None:
            self.cache_outstanding_queries = {}
        else:
            self.cache_outstanding_queries = cache
        UserAuthnMethod.__init__(self, srv)
        self.return_to = return_to
        self.idp_query_param = "IdpQuery"
        if bindings:
            self.bindings = bindings
        else:
            self.bindings = [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST,
                             BINDING_HTTP_ARTIFACT]
        self.verification_endpoint = verification_endpoint
        #Configurations for the SP handler. (pyOpSamlProxy.client.sp.conf)
        self.sp_conf = importlib.import_module(spconf)
        #self.sp_conf.BASE = self.sp_conf.BASE % url
        ntf = NamedTemporaryFile(suffix="pyoidc.py", delete=True)
        ntf.write("CONFIG = " + str(self.sp_conf.CONFIG).replace("%s", url))
        ntf.seek(0)
        self.sp = Saml2Client(config_file="%s" % ntf.name)
        mte = lookup.get_template("unauthorized.mako")
        argv = {
            "message": "You are not authorized!",
        }
        self.not_authorized = mte.render(**argv)


    def __call__(self, query, *args, **kwargs):
        (done, response) = self._pick_idp(query)
        if done == 0:
            entity_id = response
            # Do the AuthnRequest
            resp = self._redirect_to_auth(self.sp, entity_id, query)
            return resp
        return response

    def verify(self, request, cookie, path, requrl, **kwargs):
        """
        Verifies if the authentication was successful.

        :rtype : Response
        :param request: Contains the request parameters.
        :param cookie: Cookies sent with the request.
        :param kwargs: Any other parameters.
        :return: If the authentication was successful: a redirect to the
        return_to url. Otherwise a unauthorized response.
        :raise: ValueError
        """
        binding = None
        if path == "/" + self.sp_conf.ASCPOST:
            binding = BINDING_HTTP_POST
        if path == "/" + self.sp_conf.ASCREDIRECT:
            binding = BINDING_HTTP_REDIRECT

        saml_cookie, _ts, _typ = self.getCookieValue(cookie, self.CONST_SAML_COOKIE)
        data = json.loads(saml_cookie)

        if data[self.CONST_HASIDP] == 'False':
            (done, response) = self._pick_idp(request)
            if done == 0:
                entity_id = response
                # Do the AuthnRequest
                resp = self._redirect_to_auth(self.sp, entity_id, base64.b64decode(data[self.CONST_QUERY]) )
                return resp
            return response

        if not request:
            logger.info("Missing Response")
            return Unauthorized("You are not authorized!")

        try:
            response = self.sp.parse_authn_request_response(request["SAMLResponse"][0], binding,
                                                            self.cache_outstanding_queries)
        except UnknownPrincipal, excp:
            logger.error("UnknownPrincipal: %s" % (excp,))
            return Unauthorized(self.not_authorized)
        except UnsupportedBinding, excp:
            logger.error("UnsupportedBinding: %s" % (excp,))
            return Unauthorized(self.not_authorized)
コード例 #26
0
    def code_grant_type(self, areq):
        # assert that the code is valid
        try:
            _info = self.sdb[areq["code"]]
        except KeyError:
            err = TokenErrorResponse(
                error="invalid_grant", error_description="Unknown access grant"
            )
            return Response(
                err.to_json(), content="application/json", status="401 Unauthorized"
            )

        authzreq = json.loads(_info["authzreq"])
        if "code_verifier" in areq:
            try:
                _method = authzreq["code_challenge_method"]
            except KeyError:
                _method = "S256"

            resp = self.verify_code_challenge(
                areq["code_verifier"], authzreq["code_challenge"], _method
            )
            if resp:
                return resp

        if "state" in areq:
            if self.sdb[areq["code"]]["state"] != areq["state"]:
                logger.error("State value mismatch")
                err = TokenErrorResponse(error="unauthorized_client")
                return Unauthorized(err.to_json(), content="application/json")

        resp = self.token_scope_check(areq, _info)
        if resp:
            return resp

        # If redirect_uri was in the initial authorization request
        # verify that the one given here is the correct one.
        if "redirect_uri" in _info and areq["redirect_uri"] != _info["redirect_uri"]:
            logger.error("Redirect_uri mismatch")
            err = TokenErrorResponse(error="unauthorized_client")
            return Unauthorized(err.to_json(), content="application/json")

        issue_refresh = False
        if "scope" in authzreq and "offline_access" in authzreq["scope"]:
            if authzreq["response_type"] == "code":
                issue_refresh = True

        try:
            _tinfo = self.sdb.upgrade_to_token(
                areq["code"], issue_refresh=issue_refresh
            )
        except AccessCodeUsed:
            err = TokenErrorResponse(
                error="invalid_grant", error_description="Access grant used"
            )
            return Response(
                err.to_json(), content="application/json", status="401 Unauthorized"
            )

        logger.debug("_tinfo: %s" % _tinfo)

        atr_class = self.server.message_factory.get_response_type("token_endpoint")
        atr = atr_class(**by_schema(atr_class, **_tinfo))

        logger.debug("AccessTokenResponse: %s" % atr)

        return Response(
            atr.to_json(), content="application/json", headers=OAUTH2_NOCACHE_HEADERS
        )
コード例 #27
0
                logger.info("Missing Response")
                return Unauthorized("You are not authorized!"), False

            try:
                response = self.sp.parse_authn_request_response(
                    request["SAMLResponse"][0], binding,
                    self.cache_outstanding_queries)
            except UnknownPrincipal, excp:
                logger.error("UnknownPrincipal: %s" % (excp, ))
                return Unauthorized(self.not_authorized), False
            except UnsupportedBinding, excp:
                logger.error("UnsupportedBinding: %s" % (excp, ))
                return Unauthorized(self.not_authorized), False
            except VerificationError, err:
                logger.error("Verification error: %s" % (err, ))
                return Unauthorized(self.not_authorized), False
            except Exception, err:
                logger.error("Other error: %s" % (err, ))
                return Unauthorized(self.not_authorized), False

            if self.sp_conf.VALID_ATTRIBUTE_RESPONSE is not None:
                for k, v in self.sp_conf.VALID_ATTRIBUTE_RESPONSE.iteritems():
                    if k not in response.ava:
                        return Unauthorized(self.not_authorized), False
                    else:
                        allowed = False
                        for allowed_attr_value in v:
                            if isinstance(response.ava[k], list):
                                for resp_value in response.ava[k]:
                                    if allowed_attr_value in resp_value:
                                        allowed = True
コード例 #28
0
    def verify(self,
               request,
               cookie,
               path,
               requrl,
               end_point_index=None,
               **kwargs):
        """
        Verifies if the authentication was successful.

        :rtype : Response
        :param request: Contains the request parameters.
        :param cookie: Cookies sent with the request.
        :param kwargs: Any other parameters.
        :return: If the authentication was successful: a redirect to the
        return_to url. Otherwise a unauthorized response.
        :raise: ValueError
        """
        if isinstance(request, six.string_types):
            request = parse_qs(request)
        elif isinstance(request, dict):
            pass
        else:
            raise ValueError("Wrong type of input")

        acs = self.sp.config.getattr("endpoints",
                                     "sp")["assertion_consumer_service"]
        acs_endpoints = [(ep[0].rsplit("/", 1)[1], ep[1]) for ep in acs]
        binding = None
        path = path[1:]
        for endp in acs_endpoints:
            if path == endp[0]:
                binding = endp[1]
                break

        saml_cookie, _ts, _typ = self.getCookieValue(cookie,
                                                     self.CONST_SAML_COOKIE)
        data = json.loads(saml_cookie)

        rp_query_cookie = self.get_multi_auth_cookie(cookie)

        query = rp_query_cookie

        if not query:
            query = base64.b64decode(data[self.CONST_QUERY]).decode("ascii")

        if data[self.CONST_HASIDP] == 'False':
            (done, response) = self._pick_idp(request, end_point_index)
            if done == 0:
                entity_id = response
                # Do the AuthnRequest
                resp = self._redirect_to_auth(self.sp, entity_id, query,
                                              end_point_index)
                return resp, False
            return response, False

        if not request:
            logger.info("Missing Response")
            return Unauthorized("You are not authorized!"), False

        try:
            response = self.sp.parse_authn_request_response(
                request["SAMLResponse"][0], binding,
                self.cache_outstanding_queries)
        except UnknownPrincipal as excp:
            logger.error("UnknownPrincipal: %s" % (excp, ))
            return Unauthorized(self.not_authorized), False
        except UnsupportedBinding as excp:
            logger.error("UnsupportedBinding: %s" % (excp, ))
            return Unauthorized(self.not_authorized), False
        except VerificationError as err:
            logger.error("Verification error: %s" % (err, ))
            return Unauthorized(self.not_authorized), False
        except Exception as err:
            logger.error("Other error: %s" % (err, ))
            return Unauthorized(self.not_authorized), False

        if self.sp_conf.VALID_ATTRIBUTE_RESPONSE is not None:
            for k, v in six.iteritems(self.sp_conf.VALID_ATTRIBUTE_RESPONSE):
                if k not in response.ava:
                    return Unauthorized(self.not_authorized), False
                else:
                    allowed = False
                    for allowed_attr_value in v:
                        if isinstance(response.ava[k], list):
                            for resp_value in response.ava[k]:
                                if allowed_attr_value in resp_value:
                                    allowed = True
                                    break
                        elif allowed_attr_value in response.ava[k]:
                            allowed = True
                            break
                    if not allowed:
                        return Unauthorized(self.not_authorized), False

        # logger.info("parsed OK")'
        uid = response.assertion.subject.name_id.text
        if self.userinfo == "AA":
            if response.entity_id is not None and self.samlcache is not None:
                self.samlcache["AA_ENTITYID"] = response.entity_id
        self.setup_userdb(uid, response.ava)

        return_to = create_return_url(self.return_to, uid,
                                      **{self.query_param: "true"})
        if '?' in return_to:
            return_to += "&"
        else:
            return_to += "?"
        return_to += query

        auth_cookie = self.create_cookie(uid, "samlm")
        resp = SeeOther(str(return_to), headers=[auth_cookie])
        return resp, True
コード例 #29
0
    class SAMLAuthnMethod(UserAuthnMethod):
        CONST_QUERY = "query"
        CONST_SAML_COOKIE = "samlauthc"
        CONST_HASIDP = "hasidp"

        def __init__(self,
                     srv,
                     lookup,
                     userdb,
                     spconf,
                     url,
                     return_to,
                     cache=None,
                     bindings=None,
                     userinfo=None,
                     samlcache=None):
            """
            Constructor for the class.
            :param srv: Usually none, but otherwise the oic server.
            :param return_to: The URL to return to after a successful
            authentication.
            """
            self.userdb = userdb
            self.userinfo = userinfo

            if cache is None:
                self.cache_outstanding_queries = {}
            else:
                self.cache_outstanding_queries = cache
            UserAuthnMethod.__init__(self, srv)
            self.return_to = return_to
            self.idp_query_param = "IdpQuery"
            if bindings:
                self.bindings = bindings
            else:
                self.bindings = [
                    BINDING_HTTP_REDIRECT, BINDING_HTTP_POST,
                    BINDING_HTTP_ARTIFACT
                ]
            # TODO Why does this exist?
            self.verification_endpoint = ""
            #Configurations for the SP handler. (pyOpSamlProxy.client.sp.conf)
            self.sp_conf = importlib.import_module(spconf)
            #self.sp_conf.BASE = self.sp_conf.BASE % url
            ntf = NamedTemporaryFile(suffix="pyoidc.py", delete=True)
            ntf.write("CONFIG = " +
                      str(self.sp_conf.CONFIG).replace("%s", url))
            ntf.seek(0)
            self.sp = Saml2Client(config_file="%s" % ntf.name)
            mte = lookup.get_template("unauthorized.mako")
            argv = {
                "message": "You are not authorized!",
            }
            self.not_authorized = mte.render(**argv)
            self.samlcache = self.sp_conf.SAML_CACHE

        def __call__(self, query="", end_point_index=None, *args, **kwargs):

            (done, response) = self._pick_idp(query, end_point_index)
            if done == 0:
                entity_id = response
                # Do the AuthnRequest
                resp = self._redirect_to_auth(self.sp, entity_id, query,
                                              end_point_index)
                return resp
            return response

        def verify(self,
                   request,
                   cookie,
                   path,
                   requrl,
                   end_point_index=None,
                   **kwargs):
            """
            Verifies if the authentication was successful.

            :rtype : Response
            :param request: Contains the request parameters.
            :param cookie: Cookies sent with the request.
            :param kwargs: Any other parameters.
            :return: If the authentication was successful: a redirect to the
            return_to url. Otherwise a unauthorized response.
            :raise: ValueError
            """
            if isinstance(request, basestring):
                request = parse_qs(request)
            elif isinstance(request, dict):
                pass
            else:
                raise ValueError("Wrong type of input")

            acs = self.sp.config.getattr("endpoints",
                                         "sp")["assertion_consumer_service"]
            acs_endpoints = [(ep[0].rsplit("/", 1)[1], ep[1]) for ep in acs]
            binding = None
            path = path[1:]
            for endp in acs_endpoints:
                if path == endp[0]:
                    binding = endp[1]
                    break

            saml_cookie, _ts, _typ = self.getCookieValue(
                cookie, self.CONST_SAML_COOKIE)
            data = json.loads(saml_cookie)

            rp_query_cookie = self.get_multi_auth_cookie(cookie)

            query = rp_query_cookie

            if not query:
                query = base64.b64decode(data[self.CONST_QUERY])

            if data[self.CONST_HASIDP] == 'False':
                (done, response) = self._pick_idp(request, end_point_index)
                if done == 0:
                    entity_id = response
                    # Do the AuthnRequest
                    resp = self._redirect_to_auth(self.sp, entity_id, query,
                                                  end_point_index)
                    return resp, False
                return response, False

            if not request:
                logger.info("Missing Response")
                return Unauthorized("You are not authorized!"), False

            try:
                response = self.sp.parse_authn_request_response(
                    request["SAMLResponse"][0], binding,
                    self.cache_outstanding_queries)
            except UnknownPrincipal, excp:
                logger.error("UnknownPrincipal: %s" % (excp, ))
                return Unauthorized(self.not_authorized), False
            except UnsupportedBinding, excp:
                logger.error("UnsupportedBinding: %s" % (excp, ))
                return Unauthorized(self.not_authorized), False
コード例 #30
0
ファイル: provider.py プロジェクト: zack53/pyoidc
    def token_endpoint(self,
                       request="",
                       authn="",
                       dtype="urlencoded",
                       **kwargs):
        """
        Provide clients with access tokens.

        :param authn: Auhentication info, comes from HTTP header.
        :param request: The request.
        :param dtype: deserialization method for the request.
        """
        logger.debug("- token -")
        logger.debug("token_request: %s" % sanitize(request))

        areq = self.server.message_factory.get_request_type(
            "token_endpoint")().deserialize(request, dtype)

        # Verify client authentication
        try:
            client_id = self.client_authn(self, areq, authn)
        except (FailedAuthentication, AuthnFailure) as err:
            logger.error(err)
            error = TokenErrorResponse(error="unauthorized_client",
                                       error_description="%s" % err)
            return Unauthorized(error.to_json(), content="application/json")

        logger.debug("AccessTokenRequest: %s" % sanitize(areq))

        # `code` is not mandatory for all requests
        if "code" in areq:
            try:
                _info = self.sdb[areq["code"]]
            except KeyError:
                logger.error("Code not present in SessionDB")
                error = TokenErrorResponse(error="unauthorized_client",
                                           error_description="Invalid code.")
                return Unauthorized(error.to_json(),
                                    content="application/json")

            resp = self.token_scope_check(areq, _info)
            if resp:
                return resp
            # If redirect_uri was in the initial authorization request verify that they match
            if ("redirect_uri" in _info
                    and areq["redirect_uri"] != _info["redirect_uri"]):
                logger.error("Redirect_uri mismatch")
                error = TokenErrorResponse(
                    error="unauthorized_client",
                    error_description="Redirect_uris do not match.",
                )
                return Unauthorized(error.to_json(),
                                    content="application/json")
            if "state" in areq:
                if _info["state"] != areq["state"]:
                    logger.error("State value mismatch")
                    error = TokenErrorResponse(
                        error="unauthorized_client",
                        error_description="State values do not match.",
                    )
                    return Unauthorized(error.to_json(),
                                        content="application/json")

        # Propagate the client_id further
        areq.setdefault("client_id", client_id)
        grant_type = areq["grant_type"]
        if grant_type == "authorization_code":
            return self.code_grant_type(areq)
        elif grant_type == "refresh_token":
            return self.refresh_token_grant_type(areq)
        elif grant_type == "client_credentials":
            return self.client_credentials_grant_type(areq)
        elif grant_type == "password":
            return self.password_grant_type(areq)
        else:
            raise UnSupported("grant_type: {}".format(grant_type))