1

TLDR:

I am trying to

  1. validate a Azure AD B2C access token in my Flask web API
  2. use scopes from that access token to authorize calling protected resources
  3. use timely and secure solutions such as PKCE for OAuth 2.0.

what already works:

[ client app ] -- authenticate & get access token for api --> [ Azure AD B2C ] OK

[ client app ] -- send access token to backend api (resource server) --> [ flask api ] OK

where this question looks for help:

[ flask api ] -- verify if token is valid --> [ ... ]

[ flask api ] -- verify if scopes of access token are valid to access protected resource --> [ ... ]

What is the best way to accomplish this within Flask (commonly used libraries, workflows)?


Please read for context:

I am new to authenticating webapps with Azure AD B2C. I have previously used flask-jwt-extended library to authorize and authenticate my Flask web apis where the user database was on my own server (I believe this is called 'implicit flow').

The whole 'modern' identity ecosystem is quite overwhelming and the documentation from Microsoft on using their solutions is very demanding. I have gone through most of their articles and tutorials thoroughly but some things seem still unclear.

My client app (Vue.js SPA application) fetches an access token from Azure and then sends it in the header of a HTTP request to my flask API (=resource server). There I need to validate if the token is valid and unmodified. Then I need to check if the scopes of the access token authorize calling a specific endpoint / resource. Below is the architecture.

enter image description here

Microsoft has written a tutorial to accomplish this, but it is only available through .NET or node. I am looking for a Python solution.

I am looking for a secure and sustainable solution for this problem and I am really suprised that this workflow seems not very prominent. Of course it is possible that I miss an important concept or maybe I am making things too complicated. This is exactly why I wrote this question, to get insight on a complex topic for myself and all Flask users who need to address this in the future.

Thank you for sharing your advice or solution.


Other solutions I have looked at:

https://pypi.org/project/flask-azure-oauth --> this seems to be a very tidy and functional library, however I was not able to make it work for my specific use case (opened GitHub issue)

https://github.com/RobertoPrevato/PythonJWTDemo --> a frequently referenced solution using cryptography, but it lacks the implementation of scopes.

https://github.com/cljung/py-rest-api --> builds on Roberto Prevatos solution and also includes scopes. The problem here is that this seems to rely in implicit flow, but on the Azure resources everybody talks about using PKCE and to avoid implicit flow.

6
  • PKCE is intended only for securely exchanging authorisation codes within a browser (because browsers should never handle the client secret); if you're exchanging the auth code from a flask app then the browser is not involved, so it's perfectly safe to send the client secret from the service, and no need for PKCE. Oct 27, 2022 at 11:33
  • I wasn't sure about PKCE so thank you for your clarification. However, I am not sure what you mean by 'exchanging the auth code from a flask app'. Would be nice to have more context so I can better understand this comment :)
    – linus
    Oct 27, 2022 at 11:40
  • By "exchanging the auth code" I mean the OAuth2/OIDC step which happens after the user is authenticated, to request their token. I think it might be useful to focus on OAuth2 (and OpenIdConnect) concepts more generally than anything specific to do with Azure; indeed some of the documentation and blogs from Auth0 might be better at explaining the topic as a whole than the Microsoft or Azure docs: auth0.com/docs/get-started/… (The flask app is the 'client' as far as the identity server is concerned) Oct 27, 2022 at 11:42
  • thanks, will look at that article.. I was certain that in my context my Vue frontend would be referred to as 'client' and my flask api as 'resource server'. Is that false?
    – linus
    Oct 27, 2022 at 11:48
  • Ah, sorry, in which case you will certainly need PKCE if your users are authenticating from a Vue app since that is running inside the browser; from the question I was under the impression that your web app was also using flask. But that means the majority of the real work is already happening in that app -- as far as the API receiving the token is concerned, there's no real need to care about any communication with the identity server because all of that will have happened already; the token by itself should contain a signature which you can verify by knowing the signing key. Oct 27, 2022 at 11:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.