I'm trying to use Flask-oidc in a simple flask application in order to add authentication via keycloak.
However, once I log-in with valid credentials it goes back to /oidc_callback which doesn't exist.
The flask logs show a lot of attempts of redirect with 302 result code:
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 -
...
And after a while of trying I get also this error in the console:
oauth2client.client.FlowExchangeError
oauth2client.client.FlowExchangeError: invalid_grantCode not valid
This is my flask app code:
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'])
This is my 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"
}
}
In my Keycloak admin console I have set-up my client and as far as I understand, the fact that it shows the keycloak login screen properly is because it's configured as expected, however I cannot make work the app once the login is performed.
I also tried to override the default callback (which I'm not clear about if I have to implement it or not btw):
For that I added this (taken from the docs):
OVERWRITE_REDIRECT_URI='http://localhost:5001/custom_callback'
@app.route('/custom_callback')
@oidc.custom_callback
def callback(data):
return 'Hello. You submitted %s' % data
And this to my keycloak.json:
"redirect_uris": [
"http://localhost:5001/custom_callback"
],
But no success in recognizing the logged in user. Though I see a state var in the querystring.. what should I do with that?
What am I missing?
Should I implement a custom callback? in that case can anybody give an example of how to make my flask app aware of the user logged in?
Thanks a lot in advance!
I just had the same problem. The continuous redirects seemed to come from flask_oidc wanting to set an 'oidc_id_token' but my browser was not storing the cookie since it was marked 'Secure', meaning that it will only store if transferred over https and not when using plain http.
To solve this you can update your app.config values as follows: