Skip to content

Commit dd55bfa

Browse files
committed
Add MSAL
Login fix
1 parent 6aedd60 commit dd55bfa

33 files changed

+1064
-248
lines changed

.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Copy this file as .env.local and replace the values with your own
2+
VITE_MSAL_CLIENT_ID=<your-client-id>

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,3 +396,6 @@ FodyWeavers.xsd
396396

397397
# JetBrains Rider
398398
*.sln.iml
399+
dist
400+
.env.local
401+
.DS_Store

README.md

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Steps
22

3+
Register a new app in Entra Id
4+
https://learn.microsoft.com/en-us/entra/identity-platform/scenario-spa-app-registration
5+
36
Scaffold a new React/Typescript app.
47
https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts
58

@@ -14,37 +17,39 @@ npm run dev
1417
Install the MSAL React package.
1518

1619
```
17-
npm install react react-dom
1820
npm install @azure/msal-react @azure/msal-browser
1921
```
2022

21-
# React + TypeScript + Vite
23+
https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-react-samples/typescript-sample/README.md
24+
25+
## Setup Entra Id App Registration
26+
27+
To run the app you will need an Azure subscription so that you can create an Entra Id App Registration. You can either do that manually in the Azure portal or by using the Azure CLI and the following steps.
2228

23-
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
29+
1. Install Azure CLI (if you haven't already): Follow the installation instructions for your operating system from the [official Azure CLI documentation](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli).
30+
31+
2. Sign in to Azure
32+
33+
```
34+
az login --tenant "your-tenant-id"
35+
```
2436

25-
Currently, two official plugins are available:
37+
3. Create the app registration and note the "appId" (client Id) and "id" (object id) that is output in the json:
2638

27-
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
28-
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
39+
```
40+
az ad app create --display-name "YourAppName" --sign-in-audience "AzureADMultipleOrgs"
41+
```
2942

30-
## Expanding the ESLint configuration
43+
4. Add a SPA redirect URI, replace <your-app-object-id> in the following command with the "id" from step 3:
3144

32-
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
45+
```
46+
az rest --method PATCH --uri 'https://graph.microsoft.com/v1.0/applications/<your-app-object-id>' --headers 'Content-Type=application/json' --body {"spa":{"redirectUris":["http://localhost:5173/"]}}'
47+
```
3348

34-
- Configure the top-level `parserOptions` property like this:
49+
5. Add Microsoft Graph API permissions, replace your-app-client-id in the following command with the "appId" from step 3:
3550

36-
```js
37-
export default {
38-
// other rules...
39-
parserOptions: {
40-
ecmaVersion: "latest",
41-
sourceType: "module",
42-
project: ["./tsconfig.json", "./tsconfig.node.json"],
43-
tsconfigRootDir: __dirname,
44-
},
45-
};
51+
```
52+
az ad app permission add --id "your-app-client-id" --api 00000003-0000-0000-c000-000000000000 --api-permissions 311a71cc-e848-46a1-bdf8-97ff7156d8e6=Scope
4653
```
4754

48-
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
49-
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
50-
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
55+
6. Edit authConfig.ts and replace the clientId with the "appId" from step 3. You should now be able to run the app and login.

index.html

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
5+
<link rel="icon" type="image/svg+xml" href="./assets/entra.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Vite + React + TS + Tailwind</title>
7+
<title>React MSAL Demo</title>
88
</head>
9-
<body
10-
class="text-base bg-white dark:bg-slate-800 text-slate-900 dark:text-white">
9+
<body>
1110
<div id="root"></div>
1211
<script type="module" src="/src/main.tsx"></script>
1312
</body>

package-lock.json

Lines changed: 21 additions & 197 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/vite.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/App.tsx

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/CustomNavigationClient.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { NavigationClient, NavigationOptions } from '@azure/msal-browser';
2+
import { AnyRouter } from '@tanstack/react-router';
3+
4+
export class CustomNavigationClient extends NavigationClient {
5+
private readonly router: AnyRouter;
6+
7+
constructor(router: AnyRouter) {
8+
super();
9+
this.router = router;
10+
}
11+
12+
async navigateInternal(url: string, options: NavigationOptions): Promise<boolean> {
13+
const relativePath = url.replace(window.location.origin, '');
14+
15+
console.debug('CustomNavigationClient navigating to: ', relativePath, options);
16+
17+
if (options.noHistory) {
18+
await this.router.navigate({ replace: true, to: relativePath });
19+
} else {
20+
await this.router.navigate({ to: relativePath });
21+
}
22+
23+
return false;
24+
}
25+
}

0 commit comments

Comments
 (0)