python - Oauth2 No grant found for state in flask and oic.oauth2 package -
i trying implement oauth2 authentication using openid connect workflow cloudfoundry uaa backend authentication provider in python flask application using oic.oauth2.
i encountering issue encounter "no grant found state" error when trying access token request though can curl , obtain access token via post
curl -k 'https://172.17.0.114:8443/oauth/token' -i -x post -h 'accept: application/json' -h 'content-type: application/x-www-form-urlencoded' -d 'client_id=ga4gh_server&client_secret=ga4gh_server&grant_type=authorization_code&response_type=id_token&code=1n3ilw&state=cybafdwl79yu19lcedodalmd&token_format=opaque&redirect_uri=https%3a%2f%2f172.17.0.107%2fga4gh%2foauth2callback' http/1.1 200 ok server: apache-coyote/1.1 cache-control: no-cache, no-store, max-age=0, must-revalidate pragma: no-cache expires: 0 strict-transport-security: max-age=31536000 ; includesubdomains x-xss-protection: 1; mode=block x-frame-options: deny x-content-type-options: nosniff cache-control: no-store pragma: no-cache content-type: application/json;charset=utf-8 transfer-encoding: chunked date: fri, 15 jul 2016 20:45:05 gmt {"access_token":"2f57ef6dd73c482cac5aa7b8826ba8b7","token_type":"bearer","id_token":"eyjhbgcioijiuzi1niisimtpzci6imxlz2fjes10b2tlbi1rzxkilcj0exaioijkv1qifq.eyjzdwiioijlzmy5mjfjmi0wmddiltqwndgtogzlzc01zmfjnjm1njkyzmmilcj1c2vyx25hbwuioijyemhvdsisim9yawdpbii6imxkyxailcjpc3mioijodhrwoi8vbg9jywxob3n0ojgwodavdwfhl29hdxrol3rva2vuiiwicmv2b2nhymxlijp0cnvllcjub25jzsi6imfqahmzz2v2nhq4vejeqjf6vhzcykpkucisimnsawvudf9pzci6imdhngdox3nlcnzlciisimf1zci6wyjnytrnaf9zzxj2zxiixswiemlkijoidwfhiiwiz3jhbnrfdhlwzsi6imf1dghvcml6yxrpb25fy29kzsisinvzzxjfawqioijlzmy5mjfjmi0wmddiltqwndgtogzlzc01zmfjnjm1njkyzmmilcjhenaioijnytrnaf9zzxj2zxiilcjzy29wzsi6wyjvcgvuawqixswiyxv0af90aw1lijoxndy4nje0ntu3lcjlehaioje0njg2ntg3mdusimlhdci6mtq2odyxntuwnswianrpijoimmy1n2vmnmrknznjndgyy2fjnwfhn2i4odi2yme4yjcilcjlbwfpbci6inj6ag91qgjjz3njlmnhiiwicmv2x3npzyi6imiymzy1zdu1iiwiy2lkijoiz2e0z2hfc2vydmvyin0.bda3flrmgtcpuumw6lav89mwdqsirkwi4-l0qvon7qa","refresh_token":"2f57ef6dd73c482cac5aa7b8826ba8b7-r","expires_in":43199,"scope":"openid","nonce":"ajhs3gev4t8tbdb1ztvbbjjp","jti":"2f57ef6dd73c482cac5aa7b8826ba8b7"}
the flask application generates 24 key random 'nonce' , 'state' identify seems 'state' not getting parsed correctly causing access token request fail :(.
here code deals oauth2callback, implemented using pyoidc
if app.oidcclient none: raise exceptions.notimplementedexception() response = dict(flask.request.args.iteritems(multi=true)) #aresp = app.oidcclient.parse_response( # message.authorizationresponse, # info=response, # sformat='dict') sessstate = flask.session.get('state') #respstate = aresp['state'] respstate = sessstate code = flask.request.args.get('code') #if (not isinstance(aresp, message.authorizationresponse) or # respstate != sessstate): # raise exceptions.notauthenticatedexception() if respstate != sessstate: raise exceptions.notauthenticatedexception() args = { "client_id": app.oidcclient.client_id, "client_secret": app.oidcclient.client_secret, "grant_type" : 'authorization_code', "response_type" : 'token', #"code" : aresp['code'], "code" : code, "redirect_uri": app.oidcclient.redirect_uris[0] } atr = app.oidcclient.do_access_token_request( scope=["openid"], state=respstate, request_args=args) if not isinstance(atr, message.accesstokenresponse): raise exceptions.notauthenticatedexception() atrdict = atr.to_dict() if flask.session.get('nonce') != atrdict['id_token']['nonce']: #if flask.session.get('nonce') != atrdict['nonce']: raise exceptions.notauthenticatedexception() key = oic.oauth2.rndstr(secret_key_length) flask.session['key'] = key #app.tokenmap[key] = aresp["code"], respstate, atrdict app.tokenmap[key] = code, respstate, atrdict # flask.url_for broken. relies on server_name both name # , port, , defaults 'localhost' if not found. therefore # need fix returned url indexurl = flask.url_for('index', _external=true) indexparts = list(urlparse.urlparse(indexurl)) if ':' not in indexparts[1]: indexparts[1] = '{}:{}'.format(socket.gethostname(), app.myport) indexurl = urlparse.urlunparse(indexparts) response = flask.redirect(indexurl) return response
upon success auth server login, server redirected callback url following parameters.
https://172.17.0.107/ga4gh/oauth2callback#token_type=bearer&id_token=eyjhbgcioijiuzi1niisimtpzci6imxlz2fjes10b2tlbi1rzxkilcj0exaioijkv1qifq.eyjzdwiioijlzmy5mjfjmi0wmddiltqwndgtogzlzc01zmfjnjm1njkyzmmilcj1c2vyx25hbwuioijyemhvdsisim9yawdpbii6imxkyxailcjpc3mioijodhrwoi8vbg9jywxob3n0ojgwodavdwfhl29hdxrol3rva2vuiiwibm9uy2uioijhamhzm2dldjr0ofrcreixelr2qmjkslailcjjbgllbnrfawqioijnytrnaf9zzxj2zxiilcjhdwqiolsiz2e0z2hfc2vydmvyil0sinppzci6invhysisinvzzxjfawqioijlzmy5mjfjmi0wmddiltqwndgtogzlzc01zmfjnjm1njkyzmmilcjhenaioijnytrnaf9zzxj2zxiilcjzy29wzsi6wyjvcgvuawqixswiyxv0af90aw1lijoxndy4nje0ntu3lcjlehaioje0njg2ntg2ndysimlhdci6mtq2odyxntq0niwianrpijoimgy2ntiyy2e3ntdlndnizwi1owu2mgnimmqzywzjzmiilcjlbwfpbci6inj6ag91qgjjz3njlmnhiiwicmv2x3npzyi6imiymzy1zdu1iiwiy2lkijoiz2e0z2hfc2vydmvyin0.txc1kp2nt_8clam0gyk_rcdeetqio39j_c3jtultdm4&code=1n3ilw&state=cybafdwl79yu19lcedodalmd&expires_in=43199&nonce=ajhs3gev4t8tbdb1ztvbbjjp&jti=0f6522ca757e43beb59e60cb2d3afcfb
however, seems cant parse state arg off callback url reason in order proceed access token request.
any idea how fix appreciated!
thank much!
Comments
Post a Comment