Flask-OIDC с keycloak - обратный вызов по умолчанию oidc_callback не работает - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь использовать Flask-oidc в простом приложении-фляге, чтобы добавить аутентификацию через keycloak.

Однако, когда я вхожу с действительными учетными данными, он возвращается к / oidc_callback, который не 'не существует.

Журналы фляг показывают много попыток перенаправления с кодом результата 302:

127.0.0.1 - - [26/Nov/2018 10:56:54] "GET /oidc_callback?state=eyJjc3JmX3Rva2VuIjogIlluRDc0UUVLVGhRRkw5TGtuRU9RZGprNTBheVk1cERkIiwgImRlc3RpbmF0aW9uIjogImV5SmhiR2NpT2lKSVV6STFOaUo5LkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk5UQXdNUzlzYjJkcGJpSS50MVVCRUszbFBxSmZRSzkzMHB5UktBNUZibmNtU0h6TElLblgweXgtTElJIn0%3D&session_state=96eb0bd8-a4a3-49a5-a00c-f4d621cd68e0&code=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..T5U8hwYX2ot7Llzo39-cyw.4r-lLPZ1So1j4jPqfVwW5zKgtFjMR_f38ls71SwyqrwLVnE-OfZIi0O74pgzNLQEhxFu2nT-o-7_iNuqv5EIHuaIk_mp-xAY7TlaCViM9NvEDvs78iTTmLwPHsDI20SWuPS08K1wING9CXjhZLudLsBAoWRomFHGfDI_Xyd90lb0wWa73vgcMoeatlt1sEbJTo7XxuDBg-JvyzGfqclvuh5bk848q-07tkDsTKETIK-0wLxb-vUaoqkYmqRVQ3-p.PP0YzjGpjvIqCTNCk3IZTQ HTTP/1.1" 302 -
127.0.0.1 - - [26/Nov/2018 10:56:54] "GET /login HTTP/1.1" 302 -
127.0.0.1 - - [26/Nov/2018 10:56:54] "GET /oidc_callback?state=eyJjc3JmX3Rva2VuIjogIlluRDc0UUVLVGhRRkw5TGtuRU9RZGprNTBheVk1cERkIiwgImRlc3RpbmF0aW9uIjogImV5SmhiR2NpT2lKSVV6STFOaUo5LkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk5UQXdNUzlzYjJkcGJpSS50MVVCRUszbFBxSmZRSzkzMHB5UktBNUZibmNtU0h6TElLblgweXgtTElJIn0%3D&session_state=96eb0bd8-a4a3-49a5-a00c-f4d621cd68e0&code=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..JpVESxYMF7ApS07y_cOxmA.FRX0kTvi_YvRTYnA8OVmkuEHDrVr8cf9Xa9zk2KfXovb4f9vpz6oIcuqjM-EYVfC5PVLYObhVQWW9HZW4Omcewpp-t9M2z7YRZqMAuyeYAsN7_uctScoh6Q634YDSlXiyXnQ81zg3VwVC_C3pWjVnlm8ZLKb5mRAnMDe4li3FXj9OYWlzJu3Ti18TOw2ig2eB0H0D-jdMcMS4Y8CtLOX_IEKQs6f6IXgl6jpo7uDYvKnwQ11zVaX-Bvw8oan79M2.ZwuIdSCc4QYv2imcbp2Tig HTTP/1.1" 302 -
127.0.0.1 - - [26/Nov/2018 10:56:54] "GET /login HTTP/1.1" 302 -
127.0.0.1 - - [26/Nov/2018 10:56:54] "GET /oidc_callback?state=eyJjc3JmX3Rva2VuIjogIlluRDc0UUVLVGhRRkw5TGtuRU9RZGprNTBheVk1cERkIiwgImRlc3RpbmF0aW9uIjogImV5SmhiR2NpT2lKSVV6STFOaUo5LkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk5UQXdNUzlzYjJkcGJpSS50MVVCRUszbFBxSmZRSzkzMHB5UktBNUZibmNtU0h6TElLblgweXgtTElJIn0%3D&session_state=96eb0bd8-a4a3-49a5-a00c-f4d621cd68e0&code=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..4SU_gWqEUykjTc78z47zYg.TzPRPlLCmJ7Ofzp5wHMwJam4pmc21_qo0p8bIpULbDE8Q39IESxSO2Sxqvxi67xnNXL90CqbG5uRt3k_2oDPzFUCjoNw0EDibiqSPlnuMNgizGSCXAyVV8DafMJqTGhnbHUUpGVqLzMosIlfwM14jhjXFick0GaC10TPFFdiGZdfVFZlSH95XtrGQ-e9dfgpvi5ioPhlQ1S9Eo9kqSh9WwhOCfGRZe9GNLNFtUT9YCPHHmLirRNLc5NiOdm-kH3L.2Mmopk3YJ0_AiCjk2ArKwQ HTTP/1.1" 302 -
...

И после некоторого времени попытки я получаю также ошибку в консоли:

oauth2client.client.FlowExchangeError
oauth2client.client.FlowExchangeError: invalid_grantCode not valid

Это мой код приложения фляги:

import json
from flask import Flask, g
from flask_oidc import OpenIDConnect

app = Flask(__name__)

app.config.from_mapping(
        SECRET_KEY='b3d6a4b1-7f8d-4499-a1ae-6faa053d5b67',
        OIDC_CLIENT_SECRETS='./keycloak.json',
        OIDC_VALID_ISSUERS=['http://localhost:8090/auth/realms/myrealm'],
        OIDC_INTROSPECTION_AUTH_METHOD='client_secret_post',
        OIDC_TOKEN_TYPE_HINT='access_token',
    )

oidc = OpenIDConnect(app)


@app.route("/")
def hello():
    if oidc.user_loggedin:
        return 'Welcome %s' % oidc.user_getfield('email')
    else:
        return 'Not logged in'


@app.route('/login')
@oidc.require_login
def login():
    return 'Welcome %s' % oidc.user_getfield('email')


@app.route('/api')
@oidc.accept_token(require_token=True)
def my_api():
    return json.dumps('Welcome %s' % g.oidc_token_info['sub'])

Это мой keycloak.json:

{
  "web":
   {
     "client_id": "MyClient",
     "client_secret": "b3d6a4b1-7f8d-4499-a1ae-6faa053d5b67",
     "auth_uri": "http://localhost:8090/auth/realms/myrealm/protocol/openid-connect/auth",
     "token_uri": "http://localhost:8090/auth/realms/myrealm/protocol/openid-connect/token",
     "token_introspection_uri": "http://localhost:8090/auth/realms/myrealm/protocol/openid-connect/token/introspect",
     "realm": "myrealm",
     "ssl-required": "none",
     "resource": "MyClient"
   }
}

В моей консоли администратора Keycloak я настроил свойклиент и, насколько я понимаю, тот факт, что он показывает экран входа в систему keycloak правильно, потому что он настроен должным образом, однако я не могу заставить приложение работать после входа в систему.

enter image description here

Я также попытался переопределить обратный вызов по умолчанию (о чем я не уверен, должен ли я это реализовать или нет):

Для этого я добавил это (взято издокументы):

OVERWRITE_REDIRECT_URI='http://localhost:5001/custom_callback'

@app.route('/custom_callback')
@oidc.custom_callback
def callback(data):
    return 'Hello. You submitted %s' % data

И этона мой keycloak.json:

     "redirect_uris": [
         "http://localhost:5001/custom_callback"
     ],

Но не удалось распознать зарегистрированного пользователя.Хотя я вижу переменную состояния в строке запроса ... что мне с этим делать?

Что мне не хватает?

Должен ли я реализовать собственный обратный вызов?в таком случае кто-нибудь может привести пример того, как мое флеш-приложение узнало, что пользователь вошел в систему?

Заранее большое спасибо!

1 Ответ

0 голосов
/ 09 июля 2019

Проблема заключается в проверке iat. Эта проверка разрешит соединение, если время выдачи (должно быть меньше, чем время истечения) больше текущего времени, в противном случае эта проверка вернет false и отобразит ошибку.Таким образом, чтобы решить эту проблему, вам нужно установить «OIDC_CLOCK_SKEW» и создать сторону ключа для области видимости аудитории.

Здесь часть кода:

# step 10: check iat
    if id_token['iat'] < (time.time() -
                          current_app.config['OIDC_CLOCK_SKEW']):
        logger.error('Token issued in the past')
        return False

Я не знаю, является ли это хорошим способомили если это проблема с сервером / пакетом, но она работает для меня.Потому что невозможно иметь время выдачи> = current_time, верно?

Моя конфигурация:

app.config.update({
    'DEBUG': True,
    'TESTING': True,
    'SECRET_KEY': 'testest',
    'OIDC_CLIENT_SECRETS': 'client_secrets.json',
    'OIDC_ID_TOKEN_COOKIE_SECURE': False,
    'OIDC_REQUIRE_VERIFIED_EMAIL': False,
    'OIDC_USER_INFO_ENABLED': True,
    'OIDC_OPENID_REALM': 'fake_realm',
    'OIDC_SCOPES': ['openid', 'email', 'profile'],
    'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post',
    'OIDC_RESOURCE_CHECK_AUD': True, #Audience
    'OIDC_CLOCK_SKEW': 560 #iat must be > time.time() - OIDC_CLOCK_SKEW
}) 

Я поместил это здесь, чтобы помочь другим решить эту проблему:)

РЕДАКТИРОВАТЬ:

В вашем случае, кроме тоговам также нужно добавить «redirect_uris» в ваш json следующим образом: (это должен быть тот же самый URI, что и на стороне keycloak)

{
    "web": {
        "issuer": "https://{server_name}/auth/realms/fake_realm",
        "auth_uri": "https://{server_name}/auth/realms/fake_realm/protocol/openid-connect/auth",
        "client_id": "fake_realm",
        "client_secret": "ac981e95-f97b-******-*******-*****",
        "redirect_uris": [
            "http://localhost:5000/oidc_callback"
        ],
        "userinfo_uri": "https://{server_name}/auth/realms/fake_realm/protocol/openid-connect/userinfo",
        "token_uri": "https://{server_name}/auth/realms/fake_realm/protocol/openid-connect/token",
        "token_introspection_uri": "https://{server_name}/auth/realms/fake_realm/protocol/openid-connect/token/introspect"
    }
}
...