0

我正在努力使用烧瓶 oidc 和 keycloak 保护烧瓶 API 后端。我的项目包括一个 React 前端和一个烧瓶应用程序,作为受 Keycloak 服务器 v13.0.1 保护的 REST API。因此,我为前端创建了一个公共客户端,为后端创建了一个仅承载客户端,但我不断收到带有“需要令牌但无效消息”的 401。Flask 没有写任何关于错误原因的日志。我无法弄清楚我做错了什么,所以我希望你能帮助我。

这是 flask-oidc 的 client_secrets.json

{
  "web": {
    "issuer": "http://127.0.0.1:8080/auth/realms/reamar",
    "auth_uri": "http://127.0.0.1:8080/auth/realms/reamar/protocol/openid-connect/auth",
    "client_id": "reamar-api",
    "client_secret": "5d241a3c-d0a2-4811-b54c-d910a8e6aa7e",
    "redirect_uris": ["http://127.0.0.1:5000/*"],
    "userinfo_uri": "http://127.0.0.1:8080/auth/realms/reamar/protocol/openid-connect/userinfo",
    "token_uri": "http://127.0.0.1:8080/auth/realms/reamar/protocol/openid-connect/token",
    "token_introspection_uri": "http://127.0.0.1:8080/auth/realms/reamar/protocol/openid-connect/token/instrospect",
    "bearer_only": "true"
  }
}

这些是 flask-oidc 配置参数(它总是采用默认值)

OIDC_CLIENT_SECRETS = os.getenv("ODIC_CLIENT_SECRETS", "data/client_secrets.json")
OIDC_COOKIE_SECURE = os.getenv("OIDC_COOKIE_SECURE", False)
OIDC_ID_TOKEN_COOKIE_SECURE = os.getenv("OIDC_ID_TOKEN_COOKIE_NAME", False)
OIDC_SCOPES = os.getenv("OIDC_SCOPES", ["openid", "email", "profile"])
OIDC_USER_INFO_ENABLED = os.getenv("OIDC_USER_INFO_ENABLED", True)
OIDC_OPENID_REALM = os.getenv("OIDC_OPENID_REALM", "reamar")
OIDC_INTROSPECTION_AUTH_METHOD = os.getenv("OIDC_INTROSPECTION_AUTH_METHOD", "client_secret_post")
OIDC_RESOURCE_SERVER_ONLY = os.getenv("OIDC_RESOURCE_SERVER_ONLY", True)
OIDC_RESOURCE_CHECK_AUD = os.getenv("OIDC_RESOURCE_CHECK_AUD", False)
OIDC_REQUIRE_VERIFIED_EMAIL = os.getenv("OIDC_REQUIRE_VERIFIED_EMAIL", False)
OIDC_TOKEN_TYPE_HINT = "access_token"

这是令牌保护方法:

@TramiteEndpoint.route("/<string:numero>/", methods=["PUT"])
@content_type("application/json")
@accepts("application/json")
@OIDC.accept_token(require_token=True)
def actualizar(numero: str):
    tramite = TTramite(unknown=INCLUDE, context={"tramite": numero}).load(
        request.get_json()
    )
    if tramite.estado not in [
        EEstadoTramite.INICIADO,
        EEstadoTramite.PENDIENTE,
        EEstadoTramite.FINALIZADO,
    ]:
        raise Conflict(
            "No se puede modificar un trámite en estado {}".format(tramite.estado)
        )
    tipo = tramite.tipo
    if tipo == ETipoTramite.DJG:
        tramite = TDeclaracionJuradaGeneral(context={"tramite": numero}).load(
            request.get_json()
        )
    elif tipo == ETipoTramite.DJE:
        tramite = TDeclaracionJuradaEmpadronamiento(context={"tramite": numero}).load(
            request.get_json()
        )
    elif tipo == ETipoTramite.DJA:
        tramite = TDeclaracionJuradaActividad(context={"tramite": numero}).load(
            request.get_json()
        )
    elif tipo == ETipoTramite.DJEELL:
        tramite = TDeclaracionJuradaEfluentesLiquidos(context={"tramite": numero}).load(
            request.get_json()
        )
    elif tipo == ETipoTramite.DJRR:
        tramite = TDeclaracionJuradaResiduos(context={"tramite": numero}).load(
            request.get_json()
        )
    elif tipo == ETipoTramite.DJEEGG:
        tramite = TDeclaracionJuradaEmisionesGaseosas(context={"tramite": numero}).load(
            request.get_json()
        )
    tramite = TramiteRepository(current_app.entityManager).load(tramite)
    TramiteRepository(current_app.entityManager).guardar(tramite)
    return "", HTTPStatus.NO_CONTENT

最后这是我为客户端配置的密钥斗篷:

客户端设置 客户端凭据

4

0 回答 0