Skip to content

Commit 6b7cb85

Browse files
authored
Demonstrate B2C features (#4)
* Existing features just work in B2C. We added profile page only. * Adding a new README_B2C.md for B2C scenario * Fix wrong setting in configuration template * Change "Microsoft Graph" to "web api" * fixup! Existing features just work in B2C. We added profile page only. * fixup! Existing features just work in B2C. We added profile page only. * Address PR comment https://github.com/Azure-Samples/ms-identity-python-webapp/pull/4/files#r341675904 * Apply suggestions from Marsh's code review Co-Authored-By: Marsh Macy <mmacy@users.noreply.github.com> * Add ResetPassword behavior, and refactor based on latest master
1 parent 8e89f70 commit 6b7cb85

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

README_B2C.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
---
2+
page_type: sample
3+
languages:
4+
- python
5+
- html
6+
products:
7+
- azure-active-directory
8+
description: "This sample demonstrates a Python web application calling a web api that is secured using Azure Active Directory."
9+
urlFragment: ms-identity-python-webapp
10+
---
11+
# Integrating B2C feature of Microsoft identity platform with a Python web application
12+
13+
## About this sample
14+
15+
> This sample was initially developed as a web app to demonstrate how to
16+
> [Integrate Microsoft Identity Platform with a Python web application](https://github.com/Azure-Samples/ms-identity-python-webapp/blob/master/README.md).
17+
> The same code base can also be used to demonstrate how to
18+
> Integrate B2C of Microsoft identity platform with a Python web application.
19+
> All you need is some different steps to register your app in your own B2C tenant,
20+
> and then feed those different settings into the configuration file of this sample.
21+
22+
This sample covers the following:
23+
24+
* Update the application in Azure AD B2C
25+
* Configure the sample to use the application
26+
* Enable authentication in a web application using Azure Active Directory B2C
27+
* Access a web API using Azure Active Directory B2C
28+
29+
30+
### Overview
31+
32+
This sample demonstrates a Python web application that signs-in users with the Microsoft identity platform and calls another web api.
33+
34+
1. The python web application uses the Microsoft Authentication Library (MSAL) to obtain an access token from the Microsoft identity platform (formerly Azure AD v2.0):
35+
2. The access token is used as a bearer token to authenticate the user when calling the web api.
36+
37+
![Overview](./ReadmeFiles/topology.png)
38+
39+
40+
## Prerequisites
41+
42+
1. [Create an Azure Active Directory B2C tenant](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-tenant)
43+
1. [Register an application in Azure Active Directory B2C](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications).
44+
1. [Create user flows in Azure Active Directory B2C](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows)
45+
1. Have [Python 2.7+ or Python 3+](https://www.python.org/downloads/) installed
46+
47+
48+
## Update the application
49+
50+
In the tutorial that you completed as part of the prerequisites, you [added a web application in Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/tutorial-register-applications).
51+
To enable communication with the sample in this tutorial, you need to add a redirect URI to that application in Azure AD B2C.
52+
53+
* Modify an existing or add a new **Reply URL**, for example `http://localhost:5000/getAToken` or `https://your_domain.com:5000/getAToken`.
54+
You could use any port or any path. Later we will set this sample to match what you register here.
55+
* On the properties page, record the application ID that you'll use when you configure the web application.
56+
* Also generate a key (client secret) for your web application. Record the key that you'll use when you configure this sample.
57+
58+
59+
## Configure the sample
60+
61+
### Step 1: Clone or download this repository
62+
63+
From your shell or command line:
64+
65+
```Shell
66+
git clone https://github.com/Azure-Samples/ms-identity-python-webapp.git
67+
```
68+
69+
or download and extract the repository .zip file.
70+
71+
> Given that the name of the sample is quite long, you might want to clone it in a folder close to the root of your hard drive, to avoid file name length limitations when running on Windows.
72+
73+
74+
### Step 2: Install sample dependency
75+
76+
Install the dependencies using pip:
77+
78+
```Shell
79+
$ pip install -r requirements.txt
80+
```
81+
82+
### Step 3: Configure the sample to use your Azure AD tenant
83+
84+
In the steps below, "ClientID" is the same as "Application ID" or "AppId".
85+
86+
#### Configure the pythonwebapp project
87+
88+
> Note: if you used the setup scripts, the changes below may have been applied for you
89+
90+
1. Use the `app_config_b2c.py` template to replace `app_config.py`.
91+
1. Open the (now replaced) `app_config.py` file
92+
93+
* Update the value of `b2c_tenant` with the name of the Azure AD B2C tenant that you created.
94+
For example, replace `fabrikamb2c` with `contoso`.
95+
* Replace the value of `CLIENT_ID` with the application ID that you recorded.
96+
* Replace the value of `CLIENT_SECRET` with the key that you recorded.
97+
* Replace the value of `signupsignin_user_flow` with `b2c_1_signupsignin1`.
98+
* Replace the value of `editprofile_user_flow` with `b2c_1_profileediting1`.
99+
* Replace the value of `resetpassword_user_flow` with `b2c_1_passwordreset1`.
100+
* Replace the value of `REDIRECT_PATH` with the path part you set up in **Reply URL**.
101+
For example, `/getAToken`. It will be used by this sample app to form
102+
an absolute URL which matches your full **Reply URL**.
103+
* You do not have to configure the `ENDPOINT` and `SCOPE` right now
104+
105+
106+
## Enable authentication
107+
108+
Run app.py from shell or command line. Note that the port needs to match what you've set up in your **Reply URL**:
109+
```Shell
110+
$ flask run --port 5000
111+
```
112+
113+
You should now be able to visit `http://localhost:5000` and use the sign-in feature.
114+
This is how you enable authentication in a web application using Azure Active Directory B2C.
115+
116+
117+
## Access a web API
118+
119+
This sample itself does not act as a web API.
120+
Here we assume you already have your web API up and running elsewhere in your B2C tenant,
121+
with a specific endpoint, protected by a specific scope,
122+
and your sample app is already granted permission to access that web API.
123+
124+
Now you can configure this sample to access that web API.
125+
126+
1. Open the (now replaced) `app_config.py` file
127+
* Replace the value of `ENDPOINT` with the actual endpoint of your web API.
128+
* Replace the value of `SCOPE` with a list of the actual scopes of your web API.
129+
For example, write them as `["demo.read", "demo.write"]`.
130+
131+
Now, re-run your web app sample, and you will find a new link showed up,
132+
and you can access the web API using Azure Active Directory B2C.
133+
134+
135+
## Community Help and Support
136+
137+
Use [Stack Overflow](http://stackoverflow.com/questions/tagged/msal) to get support from the community.
138+
Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before.
139+
Make sure that your questions or comments are tagged with [`azure-active-directory` `adal` `msal` `python`].
140+
141+
If you find a bug in the sample, please raise the issue on [GitHub Issues](../../issues).
142+
143+
To provide a recommendation, visit the following [User Voice page](https://feedback.azure.com/forums/169401-azure-active-directory).
144+
145+
## Contributing
146+
147+
If you'd like to contribute to this sample, see [CONTRIBUTING.MD](/CONTRIBUTING.md).
148+
149+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
150+
151+
## More information
152+
153+
For more information, see MSAL.Python's [conceptual documentation]("https://github.com/AzureAD/microsoft-authentication-library-for-python/wiki"):
154+
155+
156+
For more information about web apps scenarios on the Microsoft identity platform see [Scenario: Web app that calls web APIs](https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-overview)
157+
158+
For more information about how OAuth 2.0 protocols work in this scenario and other scenarios, see [Authentication Scenarios for Azure AD](http://go.microsoft.com/fwlink/?LinkId=394414).

app_config_b2c.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import os
2+
3+
b2c_tenant = "fabrikamb2c"
4+
signupsignin_user_flow = "b2c_1_signupsignin1"
5+
editprofile_user_flow = "b2c_1_profileediting1"
6+
resetpassword_user_flow = "b2c_1_passwordreset1"
7+
authority_template = "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{user_flow}"
8+
9+
CLIENT_SECRET = "Enter_the_Client_Secret_Here" # Our Quickstart uses this placeholder
10+
# In your production app, we recommend you to use other ways to store your secret,
11+
# such as KeyVault, or environment variable as described in Flask's documentation here
12+
# https://flask.palletsprojects.com/en/1.1.x/config/#configuring-from-environment-variables
13+
# CLIENT_SECRET = os.getenv("CLIENT_SECRET")
14+
# if not CLIENT_SECRET:
15+
# raise ValueError("Need to define CLIENT_SECRET environment variable")
16+
17+
AUTHORITY = authority_template.format(
18+
tenant=b2c_tenant, user_flow=signupsignin_user_flow)
19+
B2C_PROFILE_AUTHORITY = authority_template.format(
20+
tenant=b2c_tenant, user_flow=editprofile_user_flow)
21+
B2C_RESET_PASSWORD_AUTHORITY = authority_template.format(
22+
tenant=b2c_tenant, user_flow=resetpassword_user_flow)
23+
24+
CLIENT_ID = "Enter_the_Application_Id_here"
25+
26+
REDIRECT_PATH = "/getAToken" # It will be used to form an absolute URL
27+
# And that absolute URL must match your app's redirect_uri set in AAD
28+
29+
# This is the resource that you are going to access in your B2C tenant
30+
ENDPOINT = ''
31+
32+
# These are the scopes that you defined for the web API
33+
SCOPE = ["demo.read", "demo.write"]
34+
35+
SESSION_TYPE = "filesystem" # So token cache will be stored in server-side session
36+

templates/auth_error.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
5+
6+
{% if config.get("B2C_RESET_PASSWORD_AUTHORITY") and "AADB2C90118" in result.get("error_description") %}
7+
<!-- See also https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-policies#linking-user-flows -->
8+
<meta http-equiv="refresh" content='0;{{_build_auth_url(authority=config["B2C_RESET_PASSWORD_AUTHORITY"])}}'>
9+
{% endif %}
510
</head>
611
<body>
712
<h2>Login Failure</h2>

templates/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ <h2>Welcome {{ user.get("name") }}!</h2>
1111
<li><a href='/graphcall'>Call Microsoft Graph API</a></li>
1212
{% endif %}
1313

14+
{% if config.get("B2C_PROFILE_AUTHORITY") %}
15+
<li><a href='{{_build_auth_url(authority=config["B2C_PROFILE_AUTHORITY"])}}'>Edit Profile</a></li>
16+
{% endif %}
17+
1418
<li><a href="/logout">Logout</a></li>
1519
<hr>
1620
<footer style="text-align: right">Powered by MSAL Python {{ version }}</footer>

templates/login.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ <h1>Microsoft Identity Python Web App</h1>
88

99
<li><a href='{{ auth_url }}'>Sign In</a></li>
1010

11+
{% if config.get("B2C_RESET_PASSWORD_AUTHORITY") %}
12+
<li><a href='{{_build_auth_url(authority=config["B2C_RESET_PASSWORD_AUTHORITY"])}}'>Reset Password</a></li>
13+
{% endif %}
14+
1115
<hr>
1216
<footer style="text-align: right">Powered by MSAL Python {{ version }}</footer>
1317
</body>

0 commit comments

Comments
 (0)