Skip to content

Commit

Permalink
Enabling HTTPS with local WebApp development (#1311)
Browse files Browse the repository at this point in the history
### Motivation and Context
This PR sets up the support for HTTPS should developers choose to enable
it. Some customers have production sites using HTTPS and want the option
to have a local development site that behaves like HTTPS.

### Description
- Update WebApp env.example with required variables
- Updated README with instructions on how to generate locally signed
certificate and how to update copilot config files accordingly.
- Added `https://localhost:3000` to AllowedOrigins in webapi config
files
  • Loading branch information
teresaqhoang authored and salmon131 committed Jun 3, 2023
1 parent ecc3f95 commit 4516280
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ FodyWeavers.xsd
*.cer
*.crt
*.key
*.pem

.env
certs/
Expand Down
3 changes: 2 additions & 1 deletion samples/apps/copilot-chat-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ First, let’s set up and verify the back-end API server is running.
yarn install
yarn start
```

> To run the WebApp with HTTPs, see [How to use HTTPS for local development](./webapp/README.md#how-to-use-https-for-local-development).

4. With the back end and front end running, your web browser should automatically launch and navigate to `http://localhost:3000`
> The first time running the front-end application may take a minute or so to start.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ resource appServiceWebConfig 'Microsoft.Web/sites/config@2022-09-01' = {
cors: {
allowedOrigins: [
'http://localhost:3000'
'https://localhost:3000'
]
supportCredentials: true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@
"alwaysOn": true,
"cors": {
"allowedOrigins": [
"http://localhost:3000"
"http://localhost:3000",
"https://localhost:3000"
],
"supportCredentials": true
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,8 @@
"alwaysOn": true,
"cors": {
"allowedOrigins": [
"http://localhost:3000"
"http://localhost:3000",
"https://localhost:3000"
],
"supportCredentials": true
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,8 @@
"alwaysOn": true,
"cors": {
"allowedOrigins": [
"http://localhost:3000"
"http://localhost:3000",
"https://localhost:3000"
],
"supportCredentials": true
},
Expand Down
3 changes: 2 additions & 1 deletion samples/apps/copilot-chat-app/webapi/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@

// CORS
"AllowedOrigins": [
"http://localhost:3000"
"http://localhost:3000",
"https://localhost:3000"
],

// The schema information for a serialized bot that is supported by this application.
Expand Down
7 changes: 7 additions & 0 deletions samples/apps/copilot-chat-app/webapp/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ REACT_APP_AAD_CLIENT_ID=

# Optional Variables
REACT_APP_SK_API_KEY=

# To enable HTTPS, uncomment the following variables
# HTTPS="true"
# Replace with your locally-trusted cert file
# SSL_CRT_FILE=local-cert.crt
# Replace with your locally-trusted cert key
# SSL_KEY_FILE=local-cert.key
2 changes: 1 addition & 1 deletion samples/apps/copilot-chat-app/webapp/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/build
/build
141 changes: 126 additions & 15 deletions samples/apps/copilot-chat-app/webapp/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,117 @@
# Copilot Chat Web App

> This learning sample is for educational purposes only and is not recommended for
production deployments.
> production deployments.
See [../README.md](../README.md) for complete instructions on setting up and running the application.

## How to use HTTPS for local development

If you want to run Copilot Chat with HTTPS, you need to create a certificate and sign it with a Certificate Authority (CA) that is trusted locally by your device and browser. You have a couple of options on how to do this:

1. (Recommended) Reusuing the [dotnet dev-certs](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-dev-certs) generated for the webapi app

> Note: the `dotnet dev-certs` command does not have a built-in option to generate a certificate for a specific IP address. It only generates a cert for `localhost`. If you need to use a specific IP address, use one of the two options below.
2. [mkcert](https://github.com/FiloSottile/mkcert#installation): a simple tool for making locally-trusted development certificates; requires no configuration
3. [Azure KeyVault certificates](https://learn.microsoft.com/en-us/azure/key-vault/certificates/certificate-scenarios): you'll need to create the certificate in Key Vault using [Portal](https://learn.microsoft.com/en-us/azure/key-vault/certificates/quick-create-portal), [Azure CLI](https://learn.microsoft.com/en-us/azure/key-vault/certificates/quick-create-cli), or [Azure PowerShell](https://learn.microsoft.com/en-us/azure/key-vault/certificates/quick-create-powershell) and then download the cert and key files to use in step 2.

### Step 1: Creating the certificate

Option 1: Reusuing the [dotnet dev-certs](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-dev-certs) generated for the webapi app.

1. Open a terminal and navigate to `samples/apps/copilot-chat-app/webapi`.
1. Run

```
dotnet dev-certs https -ep ../webapp/local-cert.crt --no-password --trust --format PEM
```

This will create a certificate for `localhost`, trust it, and export it to a PEM file including the private key.

> Note: The `--no-password` flag specifies that a password will not be used for the key on export. This is intended for testing use only.
1. The certificate and key are now exported as a pair of files in PEM format at the root of this directory (/webapp):
- local-cert.crt
- local-cert.key

Option 2: Using [mkcert](https://github.com/FiloSottile/mkcert#installation)

1. From an elevated shell, run

### Windows

On Windows, use [Chocolatey](https://chocolatey.org/)

```
choco install mkcert
```

### MacOS

On macOS, use [Homebrew](https://brew.sh/)

```
brew install mkcert
```

For installation on Linux, other operating systems, and advanced topics (e.g., supported root stores), see the [official mkcert installation guide](https://github.com/FiloSottile/mkcert#installation).

1. Create a new local certificate authority (CA) by running
```
mkcert -install
```
1. Create a new certificate with all hostnames you wish to run the app on.

> It is recommend you do this at the /webapp directory level.
Run

```
mkcert localhost 127.0.0.1 example.test
```

You should see an output that looks like this:

```
Created a new certificate valid for the following names 📜
- "localhost"
- "127.0.0.1"
- "example.test"
The certificate is at "./localhost+1.pem" and the key at "./localhost+1-key.pem" ✅
It will expire on 1 September 2025
```

> **Warning**: (from the developers of mkcert) the rootCA-key.pem file that mkcert automatically generates gives complete power to intercept secure requests from your machine. Do not share it.
### Step 2: Configuring Copilot Chat to use the certificate

1. In the webapp `.env` file, uncomment the following lines and populate with your respective certificate and key files generated in the step above.
```
...
# To enable HTTPS, uncomment the following lines
HTTPS="true"
# Replace with your locally-trusted cert file
SSL_CRT_FILE=local-cert.crt
# Replace with your locally-trusted cert key
SSL_KEY_FILE=local-cert.key
```
1. In the [webapi appsettings.json](../webapi/appsettings.json) file, find the `"AllowedOrigins"` section, and add the URLs (with ports!) that you'll be running the apps on with `https` prefixed. For instance, the `"AllowedOrigins"` section should look something like:
```
...
// CORS
"AllowedOrigins": [
"http://localhost:3000",
"https://localhost:3000",
"https://127.0.0.1:3000",
],
...
```
1. Add the same URLs (with ports!) as single-page application (SPA) redirect URIs to your Azure Active Directory (AAD) application registration. This can be done in the [Azure Portal](https://portal.azure.com).
1. Restart the `webapi` and `webapp` - Copilot Chat should be now running locally with HTTPS.

## Authentication

This sample uses the Microsoft Authentication Library (MSAL) for React to authenticate users.
Expand All @@ -14,30 +121,34 @@ Learn more about it here: https://learn.microsoft.com/en-us/azure/active-directo

Aside from debugging within browsers, you can launch a debug session in Visual Studio.

1. Open the webapp folder (i.e.`/samples/apps/copilot-chat-app/WebApp`) in Visual Studio Code.
1. Open the webapp folder (i.e.`/samples/apps/copilot-chat-app/webapp`) in Visual Studio Code.
2. Go to "Run and Debug" and select on the "Launch Edge against localhost".
> Go [here](https://code.visualstudio.com/docs/typescript/typescript-debugging) to learn more about debugging client-code in Visual Studio Code.
> Go [here](https://code.visualstudio.com/docs/typescript/typescript-debugging) to learn more about debugging client-code in Visual Studio Code.
## Serve a production build

By default, we run the app using `yarn start`, which starts a local development server. This enables some additional development behaviors and debuggings features, such as `React.StrictMode`, which will render the app twice to find bugs caused by impure rendering.

If you want to serve a production build of the WebApp (as static files) without any development-specific features,
If you want to serve a production build of the `webapp` (as static files) without any development-specific features,

1. Run

1. Run
```
yarn build
```

yarn build
```

This will generate an optimized and minified production-ready build of the app in the `/build` directory.

2. Once the build is complete, and you have the `/build` directory, run

```
yarn serve
```

yarn serve
```

This will start the server and serve the production build. You should see an output similar to:

```
Serving!
- Local: http://localhost:3000
- Network: http://192.168.0.100:3000
```
Serving!
- Local: http://localhost:3000
- Network: http://192.168.0.100:3000
```

0 comments on commit 4516280

Please sign in to comment.