Lägg till inloggningsknapp för Microsoft-autentisering i ett ensidesprogram

Lägg till Microsoft-autentisering i den här TypeScript-självstudien för att ange en inloggnings-/utloggningsknapp. Utveckla programmet med Sdk för Azure-klientsidan, @azure/msal-browser , för att tillhandahålla autentiseringsfunktioner.

Programarkitektur och funktioner

SPA som bygger på den här självstudien är React app (create-react-app) med följande uppgifter:

  • Logga in med en inloggning som stöds av Microsoft, till exempel Office 365 eller Outlook.com
  • Logga ut från programmet

För att tillhandahålla ett snabbt och enkelt ensidesprogram använder exemplet create-react-app med TypeScript. Det här klientramverket innehåller flera genvägar i typisk klientutveckling med Azure-SDK:er:

  • Paketering krävs för Azure-SDK:er som används i ett klientprogram
  • Miljövariabler i .env filen

1. Konfigurera utvecklingsmiljön

Kontrollera att följande programvara är installerad på den lokala datorn.

2. Behåll värdet för miljövariabeln

Spara en plats där du kan kopiera klient-ID-värdet för appregistreringen, till exempel en textfil. Du får det här klient-ID:t i steg 5 i nästa avsnitt. Värdet används som en miljövariabel för webbappen.

3. Skapa appregistrering för autentisering

  1. Logga inAzure Portal för standardkatalogens Appregistreringar.

  2. Välj + Ny registrering.

  3. Ange dina appregistreringsdata med hjälp av följande tabell:

    Fält Värde Beskrivning
    Name Simple Auth Tutorial Det här är appnamnet som användaren ser i behörighetsformuläret när de loggar in på din app.
    Kontotyper som stöds Konton i alla organisationskataloger (Alla Azure AD-kataloger – Multitenant) och personliga Microsoft-konton Detta omfattar de flesta kontotyper.
    Omdirigerings-URI-typ Ensidesapplikation (SPA)
    Omdirigerings-URI-värde http://localhost:3000 DEN URL som ska returneras till efter att autentiseringen har lyckats eller misslyckats.

    Ny Azure-appregistrering.

  4. Välj Register (Registrera). Vänta tills appregistreringen har slutförts.

  5. Kopiera program-ID:t (klienten) från avsnittet Översikt i appregistreringen. Du lägger till det här värdet i miljövariabeln för klientappen senare.

4. Skapa React ensidesapplikation för TypeScript

  1. I ett Bash-gränssnitt skapar du en create-react-app med TypeScript som språk:

    npx create-react-app tutorial-demo-login-button --template typescript
    
  2. Ändra till den nya katalogen och installera @azure/msal-browser autentiseringspaketet:

    cd tutorial-demo-login-button && npm install @azure/msal-browser
    
  3. Skapa en .env fil på rotnivå och lägg till följande rad:

    REACT_APP_AZURE_ACTIVE_DIRECTORY_APP_CLIENT_ID=
    

    Filen .env läses som en del av ramverket create-react-app. I den här filen kan du lagra klient-ID:t för lokal utveckling.

  4. Kopiera ditt program-ID (klient) till värdet.

5. Lägg till inloggnings- och utloggningsknappar

  1. Skapa en undermapp med namnet azure för de Azure-specifika filerna i ./src mappen .

  2. Skapa en ny fil för autentiseringskonfiguration azure i mappen med namnet och kopiera följande azure-authentication-config.ts kod:

    import { Configuration, LogLevel } from "@azure/msal-browser";
    
    const AzureActiveDirectoryAppClientId: any =
      process.env.REACT_APP_AZURE_ACTIVE_DIRECTORY_APP_CLIENT_ID;
    
    export const MSAL_CONFIG: Configuration = {
      auth: {
        clientId: AzureActiveDirectoryAppClientId,
      },
      cache: {
        cacheLocation: "sessionStorage",
        storeAuthStateInCookie: false,
      },
      system: {
        loggerOptions: {
          loggerCallback: (level, message, containsPii) => {
            if (containsPii) {
              return;
            }
            switch (level) {
              case LogLevel.Error:
                console.error(message);
                return;
              case LogLevel.Info:
                console.info(message);
                return;
              case LogLevel.Verbose:
                console.debug(message);
                return;
              case LogLevel.Warning:
                console.warn(message);
                return;
            }
          },
        },
      },
    };
    

    Den här filen läser in ditt program-ID från filen, anger session som webbläsarlagring i stället för cookies och tillhandahåller loggning som tar hänsyn .env till personlig information.

  3. Skapa en ny fil för Mellanprogram för Azure-autentisering azure i mappen med namnet och kopiera följande azure-authentication-context.ts kod:

    import {
      PublicClientApplication,
      AuthenticationResult,
      AccountInfo,
      EndSessionRequest,
      RedirectRequest,
      PopupRequest,
    } from "@azure/msal-browser";
    
    import { MSAL_CONFIG } from "./azure-authentication-config";
    
    export class AzureAuthenticationContext {
      private myMSALObj: PublicClientApplication = new PublicClientApplication(
        MSAL_CONFIG
      );
      private account?: AccountInfo;
      private loginRedirectRequest?: RedirectRequest;
      private loginRequest?: PopupRequest;
    
      public isAuthenticationConfigured = false;
    
      constructor() {
        // @ts-ignore
        this.account = null;
        this.setRequestObjects();
        if (MSAL_CONFIG?.auth?.clientId) {
          this.isAuthenticationConfigured = true;
        }
      }
    
      private setRequestObjects(): void {
        this.loginRequest = {
          scopes: [],
          prompt: "select_account",
        };
    
        this.loginRedirectRequest = {
          ...this.loginRequest,
          redirectStartPage: window.location.href,
        };
      }
    
      login(signInType: string, setUser: any): void {
        if (signInType === "loginPopup") {
          this.myMSALObj
            .loginPopup(this.loginRequest)
            .then((resp: AuthenticationResult) => {
              this.handleResponse(resp, setUser);
            })
            .catch((err) => {
              console.error(err);
            });
        } else if (signInType === "loginRedirect") {
          this.myMSALObj.loginRedirect(this.loginRedirectRequest);
        }
      }
    
      logout(account: AccountInfo): void {
        const logOutRequest: EndSessionRequest = {
          account,
        };
    
        this.myMSALObj.logout(logOutRequest);
      }
      handleResponse(response: AuthenticationResult, incomingFunction: any) {
        if(response !==null && response.account !==null) {
          this.account = response.account;
        } else {
          this.account = this.getAccount();
        }
    
        if (this.account) {
          incomingFunction(this.account);
        }
      }
      private getAccount(): AccountInfo | undefined {
        console.log(`loadAuthModule`);
        const currentAccounts = this.myMSALObj.getAllAccounts();
        if (currentAccounts === null) {
          // @ts-ignore
          console.log("No accounts detected");
          return undefined;
        }
    
        if (currentAccounts.length > 1) {
          // TBD: Add choose account code here
          // @ts-ignore
          console.log(
            "Multiple accounts detected, need to add choose account code."
          );
          return currentAccounts[0];
        } else if (currentAccounts.length === 1) {
          return currentAccounts[0];
        }
      }
    }
    
    export default AzureAuthenticationContext;
    

    Den här filen tillhandahåller autentisering till Azure för en användare med loginlogout funktionerna och .

  4. Skapa en ny fil för knappkomponentfilen för användargränssnittet i mappen azure med namnet och kopiera följande azure-authentication-component.tsx kod:

    import React, { useState } from "react";
    import AzureAuthenticationContext from "./azure-authentication-context";
    import { AccountInfo } from "@azure/msal-browser";
    
    const ua = window.navigator.userAgent;
    const msie = ua.indexOf("MSIE ");
    const msie11 = ua.indexOf("Trident/");
    const isIE = msie > 0 || msie11 > 0;
    
    // Log In, Log Out button
    const AzureAuthenticationButton = ({ onAuthenticated }: any): JSX.Element => {
      // Azure client context
      const authenticationModule: AzureAuthenticationContext = new AzureAuthenticationContext();
    
      const [authenticated, setAuthenticated] = useState<Boolean>(false);
      const [user, setUser] = useState<AccountInfo>();
    
      const logIn = (method: string): any => {
        const typeName = "loginPopup";
        const logInType = isIE ? "loginRedirect" : typeName;
    
        // Azure Login
        authenticationModule.login(logInType, returnedAccountInfo);
      };
      const logOut = (): any => {
        if (user) {
          onAuthenticated(undefined);
          // Azure Logout
          authenticationModule.logout(user);
        }
      };
    
      const returnedAccountInfo = (user: AccountInfo) => {
        // set state
        setAuthenticated(user?.name ? true : false);
        onAuthenticated(user);
        setUser(user);
      };
    
      const showLogInButton = (): any => {
        return (
          <button id="authenticationButton" onClick={() => logIn("loginPopup")}>
            Log in
          </button>
        );
      };
    
      const showLogOutButton = (): any => {
        return (
          <div id="authenticationButtonDiv">
            <div id="authentication">
              <button id="authenticationButton" onClick={() => logOut()}>
                Log out
              </button>
            </div>
          </div>
        );
      };
    
      const showButton = (): any => {
        return authenticated ? showLogOutButton() : showLogInButton();
      };
    
      return (
        <div id="authentication">
          {authenticationModule.isAuthenticationConfigured ? (
            showButton()
          ) : (
            <div>Authentication Client ID is not configured.</div>
          )}
        </div>
      );
    };
    
    export default AzureAuthenticationButton;
    

    Den här knappkomponenten loggar in en användare och skickar tillbaka användarkontot till den anropande/överordnade komponenten.

    Knapptexten och funktionen är toggled baserat på om användaren för närvarande är inloggad, avbildad med funktionen som en egenskap onAuthenticated som skickas till komponenten.

    När en användare loggar in anropar knappen Azure-autentiseringsbiblioteksmetoden, authenticationModule.loginreturnedAccountInfo med som återanropsfunktion. Det returnerade användarkontot skickas sedan tillbaka till den överordnade komponenten med onAuthenticated funktionen .

  5. Öppna filen ./src/App.tsx och ersätt all kod med följande kod för att inkludera knappkomponenten Logga in/logga ut:

    import React, { useState } from "react";
    import AzureAuthenticationButton from "./azure/azure-authentication-component";
    import { AccountInfo } from "@azure/msal-browser";
    
    function App() {
      // current authenticated user
      const [currentUser, setCurrentUser] = useState<AccountInfo>();
    
      // authentication callback
      const onAuthenticated = async (userAccountInfo: AccountInfo) => {
        setCurrentUser(userAccountInfo);
      };
    
      // Render JSON data in readable format
      const PrettyPrintJson = ({ data }: any) => {
        return (
          <div>
            <pre>{JSON.stringify(data, null, 2)}</pre>
          </div>
        );
      };
    
      // Quick link - user revokes app's permission
      const ShowPermissionRevokeLinks = () => {
        return (
          <div>
            <div><a href="https://myapps.microsoft.com" target="_blank" rel="noopener">Revoke AAD permission</a></div>
            <div><a href="https://account.live.com/consent/manage" target="_blank" rel="noopener">Revoke Consumer permission</a></div>
          </div>
        );
      };
    
      return (
        <div id="App">
          <h2>Microsoft Login Button application</h2>
          <AzureAuthenticationButton onAuthenticated={onAuthenticated} />
          {currentUser && (
            <div>
              <PrettyPrintJson data={currentUser} />
              <ShowPermissionRevokeLinks />
            </div>
          )}
        </div>
      );
    }
    
    export default App;
    

    När en användare har loggat in och autentiseringen omdirigeras tillbaka till den här appen visas objektet currentUser.

6. Kör React SPA-app med inloggningsknappen

  1. Starta Visual Studio code-terminalen:

    npm run start
    

    Titta på VSCode-integrerat meddelande om att appen är helt startad.

    Compiled successfully!
    
    You can now view js-e2e-client-azure-login-button in the browser.
    
      Local:            http://localhost:3000
      On Your Network:  http://x.x.x.x:3000
    
    Note that the development build is not optimized.
    To create a production build, use yarn build.
    
  2. Öppna webbappen i en webbläsare, http://localhost:3000 .

  3. Välj knappen Logga in i webbläsaren.

    Välj knappen **Logga in**.

  4. Välj ett användarkonto. Det behöver inte vara samma konto som du använde för att komma åt Azure Portal, men det bör vara ett konto som tillhandahåller Microsoft-autentisering.

    Välj ett användarkonto. Det behöver inte vara samma konto som du använde för att komma åt Azure Portal, men det bör vara ett konto som tillhandahåller Microsoft-autentisering.

  5. Granska popup-menyn som visar 1) användarnamn, 2) appnamn, 3) behörigheter som du godkänner och välj sedan Ja.

    Granska popup-menyn som visar 1) användarnamn, 2) appnamn, 3) behörigheter som du godkänner och välj sedan

  6. Granska informationen om användarkontot.

    Granska informationen om användarkontot.

  7. Välj knappen Logga ut från appen. Appen innehåller också praktiska länkar till Microsoft-användarappar för att återkalla behörigheter.

7. Lagra programspecifik användarinformation

Du kan också lagra användar-ID:t i din egen programdatabas för att korrelera mellan Microsoft-provideridentiteten och användarens data som krävs i ditt eget program. Tokenanspråket innehåller två ID:er som du kanske vill hålla reda på:

  • sub: Det ID som är specifikt för användaren för ditt specifika Active Directory-app-ID. Det här är det ID som du bör lagra i din egen programdatabas om du behöver korrelera dina anpassade appars data med din Microsoft Identity-provideranvändare.
  • oid:Detta är det universella användar-ID:t för alla appar i Microsoft Identity-providern. Lagra det här värdet om du behöver spåra användaren i flera appar i identitetsprovidern.

8. Rensa resurser

När du är klar med den här självstudien tar du bort programmet från Azure Portal appregistreringslistan.

Om du vill behålla appen men återkalla den behörighet som ges till appen av ditt specifika användarkonto använder du någon av följande länkar:

Nästa steg