|
| 1 | +--- |
| 2 | +title: Integrating Microsoft OAuth with Web3Auth for Decentralized Authentication |
| 3 | +image: "guides/banners/microsoft.png" |
| 4 | +description: Learn how to integrate Microsoft Github OAuth with Web3auth |
| 5 | +type: guide |
| 6 | +tags: [microsoft, oauth, authentication, github] |
| 7 | +date: Febreaury 28, 2024 |
| 8 | +author: Web3Auth Team |
| 9 | +order: 1 |
| 10 | +communityPortalTopicId: |
| 11 | +--- |
| 12 | + |
| 13 | +import SEO from "@site/src/components/SEO"; |
| 14 | + |
| 15 | +<SEO |
| 16 | + title="Integrating Microsoft OAuth with Web3Auth for Decentralized Authentication" |
| 17 | + description="Learn how to integrate Microsoft Github OAuth with Web3auth." |
| 18 | + image="https://web3auth.io/docs/content-hub/guides/banners/microsoft.png" |
| 19 | + slug="/content-hub/guides/microsoft-github-oauth" |
| 20 | +/> |
| 21 | + |
| 22 | +This guide will cover the basics of how to integrate Web3Auth with OAuth 2.0, using Microsoft Github authentication. Trying to explain all the flow |
| 23 | +and covering all the problems that can happen during the integration. Web3Auth is employed to provide Ethereum private key access and public address. |
| 24 | + |
| 25 | +Full example: https://github.com/web3auth/web3auth-byoa/microsoft-oauth-connection |
| 26 | + |
| 27 | +We use two web3auth libraries in this project: `@web3auth/ethereum-provider` and `@web3auth/node-sdk`. |
| 28 | + |
| 29 | +To install them, run: `npm install @web3auth/ethereum-provider @web3auth/node-sdk` |
| 30 | + |
| 31 | +## How it works? |
| 32 | + |
| 33 | +When integrating Web3Auth with Microsoft Login the flow looks something like this: |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +- When a user logs in with `Microsoft`, Microsoft sends a JWT `id_token` to the app. This JWT token is sent to the Web3Auth SDK's login function. |
| 38 | + |
| 39 | +- Finally, on successful validation of the JWT token, Web3Auth SDK will generate a private key for the user, in a self custodial way, resulting in |
| 40 | + easy onboarding for your user to the application. |
| 41 | + |
| 42 | +## Create a JWKS file |
| 43 | + |
| 44 | +A JWKS stands for JSON Web Key Set. It is a set of keys containing the public keys that should be used to verify any JSON Web Token (JWT) issued by |
| 45 | +the authorization server and signed using the RS256 signing algorithm. |
| 46 | + |
| 47 | +If you don't know how to create a JWKS, you can follow this |
| 48 | +[web3auth tutorial](https://web3auth.io/docs/auth-provider-setup/byo-jwt-providers#how-to-create-jwks). This file must be located on a public |
| 49 | +endpoint. To test the example, you will need to modify the file located in the root directory of the project. |
| 50 | + |
| 51 | +Both the private and the public keys, that you used to create the JWKS, must be in the server directory. In our project, they are called `private.pem` |
| 52 | +and `public.pem`. |
| 53 | + |
| 54 | +## Set up Custom JWT Verifier |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | +To create a custom verifier for your JWT Provider, you'll need the follow this steps: |
| 59 | + |
| 60 | +1. The verifier Identifier, which would be the name. This name should be used in your .ENV file as `WEB3AUTH_VERIFIER`. |
| 61 | + |
| 62 | +2. **JWT Verifier ID**: JWT Verifier ID is the unique identifier to publicly represent a user on a verifier. e.g: `sub`, `email`, or even a custom |
| 63 | + field of your JWT payload that is unique in your system for each user. In this case, we are using the `sub` field. |
| 64 | + |
| 65 | +3. **JWK Endpoint**: An endpoint containing the JWKS used to sign the JWT. In my example I'm using a static github url file. |
| 66 | + |
| 67 | +4. In the Select JWT Validation. You will add `iss` and `aud` fields. |
| 68 | + - The `iss` field is the issuer of the JWT. In this case "https://login.microsoftonline.com/" |
| 69 | + - The `aud` field is the audience of the JWT. In this case "http://login.microsoftonline.com/{AZURE_TENANT_ID}/v2.0/token" |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | +## Configure a new Application in Microsoft Entra. |
| 74 | + |
| 75 | +After creating the app, you'll need the Application (client) ID and the Directory (tenant) ID into the .ENV file. Then you can add a redirect URI (in |
| 76 | +our example is http://localhost:5005/ms/callback) |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | +Finally in "Certificates & secrets" -> Client Secret -> New client secret and copy the value to the .ENV file as `AZURE_CLIENT_SECRET`. |
| 81 | + |
| 82 | +## Create a Proof Key of Code Exchange (PKCE) |
| 83 | + |
| 84 | +The Proof Key of Code Exchange (PKCE) is an extension of the standard authorization code grant OAuth flow. It is designed to be a secure substitute |
| 85 | +for the implicit flow for single-page applications (SPA) or native applications. SPAs and native applications are vulnerable to reverse engineering |
| 86 | +practices. To create one you can go to this [PKCE generator](https://tonyxu-io.github.io/pkce-generator/). First click on "generate code Verfier" and |
| 87 | +then into "Generate Code Challenge". Both values will be used in the .ENV file as `AZURE_CODE_VERIFIER` and `AZURE_CODE_CHALLENGE`. |
| 88 | + |
| 89 | +## Running the example |
| 90 | + |
| 91 | +Execute `npm run dev`. To initiate the Microsoft OAuth flow, Open your browser to `http://localhost:5005/ms/login` |
| 92 | + |
| 93 | +Finally, after loginning in as a result, you will receive in the callback url a JSON with the user data, the JWT token, the Ethereum address and |
| 94 | +private key. |
| 95 | + |
| 96 | +```json |
| 97 | +{ |
| 98 | + "userData": { |
| 99 | + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity", |
| 100 | + "businessPhones": [], |
| 101 | + "displayName": "Display ... Name", |
| 102 | + "givenName": "Name", |
| 103 | + "jobTitle": null, |
| 104 | + "mail": null, |
| 105 | + "mobilePhone": null, |
| 106 | + "officeLocation": null, |
| 107 | + "preferredLanguage": "en", |
| 108 | + "surname": "Raw", |
| 109 | + "userPrincipalName": "data_gmail.com#EXT#@datagmail.onmicrosoft.com", |
| 110 | + "id": "63af4d94-1ea4-4b0b-aaa9-0da5d044xxxx" |
| 111 | + }, |
| 112 | + "jwtToken": "eyJhbGci ... z9HgEQOcYTg", |
| 113 | + "ethData": { |
| 114 | + "ethPrivateKey": "b070a6 ... 3536", |
| 115 | + "ethPublicAddress": ["0xb31181bd22b57f994d ... d2ff72ad0631251fd"] |
| 116 | + } |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +## Code guide |
| 121 | + |
| 122 | +In the example, we are using express for the server. This are the Endpoint that we are using: |
| 123 | + |
| 124 | +- The initial endpoint to start the Microsoft OAuth flow. |
| 125 | + |
| 126 | +```javascript |
| 127 | +app.get("/ms/login", async (req: any, res: any) => { |
| 128 | + const oauthUrl = `${MICROSOFT_URL}/${azureTenantId}/oauth2/v2.0/authorize? |
| 129 | + client_id=${azureClientId} |
| 130 | + &response_type=code |
| 131 | + &redirect_uri=${encodeURIComponent(azureRedirectUri)} |
| 132 | + &response_mode=query |
| 133 | + &scope=User.ReadBasic.All |
| 134 | + &state=w3a_microsoft |
| 135 | + &prompt=login |
| 136 | + &code_challenge=${azurCodeChallenge} |
| 137 | + &code_challenge_method=S256`; |
| 138 | + res.redirect(oauthUrl); |
| 139 | +}); |
| 140 | +``` |
| 141 | + |
| 142 | +- The Callback endpoint to receive the JWT token and exchange it for an access token. |
| 143 | + |
| 144 | +```javascript |
| 145 | +app.get("/ms/callback", async (req: any, res: any) => { |
| 146 | + const code = req.query.code; |
| 147 | + try { |
| 148 | + const accessToken = await exchangeCodeForAccessToken(code); |
| 149 | + const userData = await fetchMicrosoftUserDetails(accessToken); |
| 150 | + const jwtToken = generateJwtToken(userData); |
| 151 | + const ethData = await getPrivateKey(jwtToken, userData.id.toString()); |
| 152 | + res.json({ userData, jwtToken, ethData }); |
| 153 | + } catch (error) { |
| 154 | + res.status(500).send("Error during Microsoft authentication callback"); |
| 155 | + } |
| 156 | +}); |
| 157 | +``` |
| 158 | + |
| 159 | +In the `getPrivateKey` function, we use Web3auth to establish a connection with the provider and get both the address and the private key. |
| 160 | + |
| 161 | +```javascript |
| 162 | +const getPrivateKey = async (idToken: string, verifierId: string) => { |
| 163 | + const web3authNodeprovider = await web3auth.connect({ |
| 164 | + verifier: process.env.WEB3AUTH_VERIFIER, |
| 165 | + verifierId, |
| 166 | + idToken, |
| 167 | + }); |
| 168 | + // The private key returned here is the CoreKit Key |
| 169 | + const ethPrivateKey = await web3authNodeprovider.request({ method: "eth_private_key" }); |
| 170 | + const ethPublicAddress = await web3authNodeprovider.request({ method: "eth_accounts" }); |
| 171 | + const ethData = { |
| 172 | + ethPrivateKey, |
| 173 | + ethPublicAddress, |
| 174 | + }; |
| 175 | + return ethData; |
| 176 | +}; |
| 177 | +``` |
| 178 | + |
| 179 | +References |
| 180 | + |
| 181 | +- [Custom JWT providers in Web3auth](https://web3auth.io/docs/auth-provider-setup/byo-jwt-providers) |
| 182 | +- [Microsoft OAUTH 2.0 flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#redeem-a-code-for-an-access-token) |
| 183 | + |
| 184 | +## Conclusion |
| 185 | + |
| 186 | +By following the steps outlined here, developers can seamlessly incorporate Web3Auth into their applications. This guide serves as a comprehensive |
| 187 | +resource for developers seeking to integrate Web3Auth and Microsoft Github users authenticate with OAuth 2.0 Flow. Also can be a starting point for |
| 188 | +developers who want to integrate Web3Auth with other OAuth providers. |
0 commit comments