{"id":4070,"date":"2022-01-06T15:10:32","date_gmt":"2022-01-06T20:10:32","guid":{"rendered":"https:\/\/infotechguy.net\/?p=4070"},"modified":"2022-08-26T09:41:52","modified_gmt":"2022-08-26T13:41:52","slug":"airflow-azure-and-oauth","status":"publish","type":"post","link":"https:\/\/infotechguy.net\/?p=4070","title":{"rendered":"Airflow, Azure and OAuth"},"content":{"rendered":"\n<p>NOTE: This is an incomplete article &#8211; I will continue to publish more as I can. I have provided the needed code for &#8220;webserver_config.py&#8221; I have not included information for the &#8220;App Registration&#8221; in Azure.<\/p>\n<p>This article stems from me not finding enough information, in one place, pertaining to authenticating to <a href=\"https:\/\/airflow.apache.org\/\">Apache Airflow<\/a> leveraging OAuth and Azure.<br \/><br \/>I was able to piece what I needed together using documentation from different sources: GitHub, Flask, Apache, etc.<br \/><br \/>My hope is that this article provide you with the information needed to get authentication functional in your environment.<br \/><br \/>If you are using the Apache Airflow public helm chart &#8211; this is the code that will help get you going. This can be added to your &#8220;values.yaml&#8221; or &#8220;overrides.yaml&#8221; file.\u00a0 If not using a helm chart, then add the python portion &#8211; starting with the first &#8220;from&#8221; to the end of the code block and add it to your &#8220;webserver_config.py&#8221; file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>webserver:\n  service:\n    type: NodePort\n  webserverConfig: |\n    \n    from airflow.www.security import AirflowSecurityManager\n    import logging\n    from typing import Dict, Any, List, Union\n    from flask_appbuilder.security.manager import AUTH_OAUTH\n    import os\n\n    # basedir = os.path.abspath(os.path.dirname(__file__))\n\n    WTF_CSRF_ENABLED = True\n    # SQLALCHEMY_DATABASE_URI = conf.get(\"core\", \"SQL_ALCHEMY_CONN\")\n\n    AUTH_TYPE = AUTH_OAUTH\n    AUTH_ROLES_SYNC_AT_LOGIN = True\n    PERMANENT_SESSION_LIFETIME = 1800 # force users to reauth after inactivity period time in seconds\n    AUTH_USER_REGISTRATION = True\n    AUTH_USER_REGISTRATION_ROLE = \"Public\"\n\n    class AzureRoleBasedSecurityManager(AirflowSecurityManager):\n        def _get_oauth_user_info(self, provider, resp):\n            if provider == \"azure\":\n                me = self._azure_jwt_token_parse(resp&#91;\"id_token\"])\n                return {\n                    \"id\": me&#91;\"oid\"],\n                    \"username\": me&#91;\"upn\"],\n                    \"name\": me&#91;\"name\"],\n                    \"email\": me&#91;\"upn\"],\n                    \"first_name\": me&#91;\"given_name\"],\n                    \"last_name\": me&#91;\"family_name\"],\n                    \"role_keys\": me&#91;\"roles\"],\n                }\n            return {}\n        oauth_user_info = _get_oauth_user_info\n\n    SECURITY_MANAGER_CLASS = AzureRoleBasedSecurityManager\n\n    # In order of least permissive - default is \"Public\" - see AUTH_USER_REGISTRATION_ROLE\n    AUTH_ROLES_MAPPING = {\n      \"Public\": &#91;\"Public\"],\n      \"Viewer\": &#91;\"Viewer\"],\n      \"User\": &#91;\"User\"],\n      \"Op\": &#91;\"Op\"],\n      \"Admin\": &#91;\"Admin\"],\n    }\n\n    OAUTH_PROVIDERS = &#91;\n      {\n        \"name\": \"azure\",\n        \"icon\": \"fa-windows\",\n        \"token_key\": \"access_token\",\n        \"remote_app\": {\n          \"client_id\": \"&lt;from Azure&gt;\",\n          \"client_secret\": \"&lt;from Azure&gt;\",\n          \"api_base_url\": \"https:\/\/login.microsoftonline.com\/&lt;from Azure&gt;\/oauth2\",\n          \"client_kwargs\": {\n            \"scope\": \"User.read name preferred_username email profile upn\",\n            \"resource\": \"&lt;from Azure&gt;\"},\n          \"access_token_url\": \"https:\/\/login.microsoftonline.com\/&lt;from Azure&gt;\/oauth2\/token\",\n          \"authorize_url\": \"https:\/\/login.microsoftonline.com\/&lt;from Azure&gt;\/oauth2\/authorize\",\n          \"request_token_url\": None,\n        },\n      },\n    ]<\/code><\/pre>\n\n\n\n<p><p><br><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>NOTE: This is an incomplete article &#8211; I will continue to publish more as I can. I have provided the needed code for &#8220;webserver_config.py&#8221; I have not included information for the &#8220;App Registration&#8221; in Azure.&#46;&#46;&#46;<\/p>\n","protected":false},"author":3,"featured_media":4269,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28],"tags":[57,112],"class_list":["post-4070","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud","tag-cloud","tag-security-2"],"_links":{"self":[{"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/posts\/4070","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/infotechguy.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4070"}],"version-history":[{"count":1,"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/posts\/4070\/revisions"}],"predecessor-version":[{"id":4137,"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/posts\/4070\/revisions\/4137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/infotechguy.net\/index.php?rest_route=\/wp\/v2\/media\/4269"}],"wp:attachment":[{"href":"https:\/\/infotechguy.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4070"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infotechguy.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4070"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infotechguy.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4070"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}