Skip to content

Commit

Permalink
Merge pull request #97 from Azure-Samples/app-service-howto
Browse files Browse the repository at this point in the history
How to deploy to App Service
  • Loading branch information
rayluo authored Mar 28, 2023
2 parents 27d6dfd + f5161e3 commit dce9db1
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 17 deletions.
9 changes: 6 additions & 3 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
FLASK_DEBUG=True
# Note: If you are using Azure App Service, go to your app's Configuration,
# and then set the following values into your app's "Application settings".

CLIENT_ID=<client id>
CLIENT_SECRET=<client secret>

# Expects a full tenant id such as "contoso.onmicrosoft.com", or its GUID
# Or leave it undefined if you are building a multi-tenant app
#TENANT_ID=<tenant id>
CLIENT_ID=<client id>
CLIENT_SECRET=<client secret>
9 changes: 5 additions & 4 deletions .env.sample.b2c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
FLASK_DEBUG=True
# Expects the display name such as "contoso"
TENANT_NAME=<tenant name>
# Note: If you are using Azure App Service, go to your app's Configuration,
# and then set the following values into your app's "Application settings".
CLIENT_ID=<client id>
CLIENT_SECRET=<client secret>
# Expects the display name such as "contoso"
TENANT_NAME=<tenant name>
SIGNUPSIGNIN_USER_FLOW=B2C_1_profile_editing
EDITPROFILE_USER_FLOW=B2C_1_reset_password
RESETPASSWORD_USER_FLOW=B2C_1_signupsignin1
RESETPASSWORD_USER_FLOW=B2C_1_signupsignin1
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ To get started with this sample, you have two options:
[Quickstart: Add sign-in with Microsoft to a Python web app](https://docs.microsoft.com/azure/active-directory/develop/web-app-quickstart?pivots=devlang-python).
* Use PowerShell scripts that automatically create the Azure AD applications and related objects (passwords, permissions, dependencies) for you, and then modify the configuration files. Follow the steps in the [App Creation Scripts README](./AppCreationScripts/AppCreationScripts.md).

# Deployment

Once you finish testing this web app locally, you can deploy it to your production.
You may choose any web app hosting services you want.
Here we will describe how to deploy it to
[Azure App Service](https://azure.microsoft.com/en-us/products/app-service).

* Follow the ["Quickstart: Deploy a Python (Django or Flask) web app to Azure App Service"](https://learn.microsoft.com/en-us/azure/app-service/quickstart-python),
but replace its sample app (which does not do user sign-in) with this web app.

* In particular, if you choose to ["deploy using Local Git" in "step 3 - Deploy your application code to Azure"](https://learn.microsoft.com/en-us/azure/app-service/quickstart-python?tabs=flask%2Cwindows%2Cazure-cli%2Clocal-git-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli#3---deploy-your-application-code-to-azure),
an [application-scope credential](https://learn.microsoft.com/en-us/azure/app-service/deploy-configure-credentials?tabs=portal#appscope)
will be automatically created with the shape as `your_app_name\$your_app_name`.
But your actual git username is only the `$your_app_name` part.

* [Configure your app's settings](https://learn.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal#configure-app-settings) to define [these environment variables](https://github.com/Azure-Samples/ms-identity-python-webapp/blob/master/.env.sample).


## Contributing

If you find a bug in the sample, please raise the issue on [GitHub Issues](../../issues).
Expand Down
4 changes: 4 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def logout():

@app.route("/")
def index():
if not (app.config["CLIENT_ID"] and app.config["CLIENT_SECRET"]):
# This check is not strictly necessary.
# You can remove this check from your production code.
return render_template('config_error.html')
if not auth.get_user():
return redirect(url_for("login"))
return render_template('index.html', user=auth.get_user(), version=identity.__version__)
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Flask>=2
# Our how-to docs will use --debug parameter which is only available in Flask 2.2+
Flask>=2.2
# If Flask-Session is not maintained in future, Flask-Session2 should work as well
Flask-Session>=0.3.2,<0.5
werkzeug>=2
Expand Down
3 changes: 1 addition & 2 deletions templates/auth_error.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
<html lang="en">
<head>
<meta charset="UTF-8">

{% if config.get("B2C_RESET_PASSWORD_AUTHORITY") and "AADB2C90118" in result.get("error_description") %} <!-- This will be reached when user forgot their password -->
<!-- See also https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-policies#linking-user-flows -->
<meta http-equiv="refresh" content='0;{{config.get("B2C_RESET_PASSWORD_AUTHORITY")}}?client_id={{config.get("CLIENT_ID")}}'>
{% endif %}
<title>Microsoft Identity Python Web App: Error</title>
</head>
<body>
<h2>Login Failure</h2>
Expand All @@ -18,4 +18,3 @@ <h2>Login Failure</h2>
<a href="{{ url_for('index') }}">Homepage</a>
</body>
</html>

18 changes: 18 additions & 0 deletions templates/config_error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft Identity Python Web App: Error</title>
</head>
<body>
<h2>Config Missing</h2>
<p>
Almost there. Did you forget to set up
<a target=_blank
href="https://learn.microsoft.com/azure/active-directory/develop/web-app-quickstart?pivots=devlang-python#step-5-configure-the-sample-app">
necessary environment variables</a> for your deployment?
</p>
<hr>
<a href="{{ url_for('index') }}">Homepage</a>
</body>
</html>
1 change: 1 addition & 0 deletions templates/display.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft Identity Python Web App: API</title>
</head>
<body>
<a href="javascript:window.history.go(-1)">Back</a> <!-- Displayed on top of a potentially large JSON response, so it will remain visible -->
Expand Down
4 changes: 4 additions & 0 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft Identity Python Web App: Index</title>
</head>
<body>
<h1>Microsoft Identity Python Web App</h1>
<h2>Welcome {{ user.get("name") }}!</h2>

<ul>
{% if config.get("ENDPOINT") %}
<li><a href='/call_downstream_api'>Call a downstream API</a></li>
{% endif %}
Expand All @@ -16,6 +18,8 @@ <h2>Welcome {{ user.get("name") }}!</h2>
{% endif %}

<li><a href="/logout">Logout</a></li>
</ul>

<hr>
<footer style="text-align: right">Powered by Identity Web {{ version }}</footer>
</body>
Expand Down
15 changes: 8 additions & 7 deletions templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft Identity Python Web App: Login</title>
</head>
<body>
<h1>Microsoft Identity Python Web App</h1>

{% if user_code %}
<ol>
<li>To sign in, type <b>{{ user_code }}</b> into
<a href='{{ auth_uri }}' target=_blank>{{ auth_uri }}</a>
to authenticate.
</li>
<li>And then <a href="{{ url_for('auth_response') }}">proceed</a>.</li>
<li>To sign in, type <b>{{ user_code }}</b> into
<a href='{{ auth_uri }}' target=_blank>{{ auth_uri }}</a>
to authenticate.
</li>
<li>And then <a href="{{ url_for('auth_response') }}">proceed</a>.</li>
</ol>
{% else %}
<li><a href='{{ auth_uri }}'>Sign In</a></li>
<ul><li><a href='{{ auth_uri }}'>Sign In</a></li></ul>
{% endif %}

{% if config.get("B2C_RESET_PASSWORD_AUTHORITY") %}
<li><a href="{{config.get('B2C_RESET_PASSWORD_AUTHORITY')}}?client_id={{config.get('CLIENT_ID')}}">Reset Password</a></li>
<a href="{{config.get('B2C_RESET_PASSWORD_AUTHORITY')}}?client_id={{config.get('CLIENT_ID')}}">Reset Password</a>
{% endif %}

<hr>
Expand Down

0 comments on commit dce9db1

Please sign in to comment.