다음을 통해 공유


자습서: Angular 애플리케이션 만들기 및 인증 준비

적용: 녹색 원 안의 흰색 확인 표시 기호. 워크포스 테넌트와 외부 테넌트(자세한 내용)

이 자습서는 Angular SPA(단일 페이지 애플리케이션) 빌드, 인증 추가 및 Microsoft ID 플랫폼을 사용하여 사용자 데이터 추출을 보여 주는 시리즈의 첫 번째 부분입니다.

이 자습서에서:

  • 새 Angular 프로젝트 만들기
  • 애플리케이션에 대한 설정 구성
  • 애플리케이션에 인증 코드 추가

필수 조건

  • Angular CLI
  • Node.js.
  • Visual Studio Code 또는 다른 코드 편집기.
  • 다음 구성을 사용하여 Microsoft Entra 관리 센터의 새 앱 등록 자세한 내용은 애플리케이션 등록참조하세요.
    • 이름: identity-client-spa
    • 지원되는 계정 유형: 이 조직 디렉터리의 계정만(단일 테넌트).
    • 플랫폼 구성: SPA(단일 페이지 애플리케이션).
    • 리디렉션 URI: http://localhost:4200/.
  • (외부 전용) 앱 등록과 연결된 사용자 흐름입니다. 자세한 내용은 외부 테넌트 앱에 대한 셀프 서비스 등록 사용자 흐름 만들기 및 사용자 흐름애플리케이션 추가를 참조하세요.

새 Angular 프로젝트 만들기

이 섹션에서는 Visual Studio Code에서 Angular CLI를 사용하여 새 Angular 프로젝트를 만듭니다. 테넌트 유형에 따라 적절한 탭을 선택합니다.

Angular 프로젝트를 처음부터 빌드하려면 다음 단계를 수행합니다.

  1. 터미널 창을 열고 다음 명령을 실행하여 새 Angular 프로젝트를 만듭니다.

    ng new msal-angular-tutorial --routing=true --style=css --strict=false
    

    이 명령은 라우팅을 사용하도록 설정된 새 Angular 프로젝트, 스타일을 지정하기 위한 CSS 및 strict 모드를 사용하지 않도록 설정한 새 msal-angular-tutorial Angular 프로젝트를 만듭니다.

  2. 프로젝트 디렉터리로 변경합니다.

    cd msal-angular-tutorial
    
  3. 앱 종속성 설치:

    npm install @azure/msal-browser @azure/msal-angular bootstrap
    

    이 명령은 npm install @azure/msal-browser @azure/msal-angular bootstrap Azure MSAL 브라우저, Azure MSAL Angular 및 부트스트랩 패키지를 설치합니다.

  4. 부트스트랩의 CSS 경로를 열고 angular.json 배열에 styles 추가합니다.

    "styles": [
        "src/styles.css",
        "node_modules/bootstrap/dist/css/bootstrap.min.css"
    ],
    

    이 코드는 부트스트랩 CSS를 파일의 스타일 배열에 angular.json 추가합니다.

  5. 홈 및 프로필 구성 요소 생성:

    ng generate component home
    ng generate component profile
    

    이 명령은 Angular 프로젝트에서 홈 및 프로필 구성 요소를 생성합니다.

  6. 프로젝트에서 불필요한 파일 및 코드를 제거합니다.

    rm src/app/app.component.css
    rm src/app/app.component.spec.ts
    rm src/app/home/home.component.css
    rm src/app/home/home.component.spec.ts
    rm src/app/profile/profile.component.css
    rm src/app/profile/profile.component.spec.ts
    

    명령은 프로젝트에서 불필요한 파일과 코드를 제거합니다.

  7. Visual Studio Code를 사용하여 app.routes.ts의 이름을 app-routing.module.ts로 변경하고, 애플리케이션 전체에서 app.routes.ts에 대한 모든 참조를 업데이트하십시오.

  8. Visual Studio Code를 사용하여 app.config.ts의 이름을 app.module.ts로 변경하고, 애플리케이션 전체에서 app.config.ts에 대한 모든 참조를 업데이트합니다.

이러한 단계를 완료하면 프로젝트 구조가 다음과 같이 표시됩니다.

.
├── README.md
├── angular.json
├── package-lock.json
├── package.json
├── src
│   ├── app
│   │   ├── app-routing.module.ts
│   │   ├── app.component.html
│   │   ├── app.component.ts
│   │   ├── app.module.ts
│   │   ├── home
│   │   │   ├── home.component.html
│   │   │   └── home.component.ts
│   │   └── profile
│   │       ├── profile.component.html
│   │       └── profile.component.ts
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   └── styles.css
├── tsconfig.app.json
└── tsconfig.json

애플리케이션 설정 구성

이 섹션에서는 인증에 대한 애플리케이션 설정을 구성합니다. 앱 등록 중에 기록된 값을 사용하여 인증을 위해 애플리케이션을 구성합니다. 테넌트 유형에 따라 적절한 탭을 선택합니다.

앱 등록 중에 기록된 값을 사용하여 인증을 위해 애플리케이션을 구성합니다. 다음 단계를 수행합니다.

  1. src/app/app.module.ts 파일을 열고 콘텐츠를 다음 코드로 바꿉니다.

    // Required for Angular multi-browser support
    import { BrowserModule } from '@angular/platform-browser';
    
    // Required for Angular
    import { NgModule } from '@angular/core';
    
    // Required modules and components for this application
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { ProfileComponent } from './profile/profile.component';
    import { HomeComponent } from './home/home.component';
    
    // HTTP modules required by MSAL
    import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
    
    // Required for MSAL
    import { IPublicClientApplication, PublicClientApplication, InteractionType, BrowserCacheLocation, LogLevel } from '@azure/msal-browser';
    import { MsalGuard, MsalInterceptor, MsalBroadcastService, MsalInterceptorConfiguration, MsalModule, MsalService, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG, MsalGuardConfiguration, MsalRedirectComponent } from '@azure/msal-angular';
    
    const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;
    
    export function MSALInstanceFactory(): IPublicClientApplication {
      return new PublicClientApplication({
        auth: {
          // 'Application (client) ID' of app registration in the Microsoft Entra admin center - this value is a GUID
          clientId: "Enter_the_Application_Id_Here",
          // Full directory URL, in the form of https://login.microsoftonline.com/<tenant>
          authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here",
          // Must be the same redirectUri as what was provided in your app registration.
          redirectUri: "http://localhost:4200",
        },
        cache: {
          cacheLocation: BrowserCacheLocation.LocalStorage,
          storeAuthStateInCookie: isIE
        }
      });
    }
    
    // MSAL Interceptor is required to request access tokens in order to access the protected resource (Graph)
    export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
      const protectedResourceMap = new Map<string, Array<string>>();
      protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read']);
    
      return {
        interactionType: InteractionType.Redirect,
        protectedResourceMap
      };
    }
    
    // MSAL Guard is required to protect routes and require authentication before accessing protected routes
    export function MSALGuardConfigFactory(): MsalGuardConfiguration {
      return { 
        interactionType: InteractionType.Redirect,
        authRequest: {
          scopes: ['user.read']
        }
      };
    }
    
    // Create an NgModule that contains the routes and MSAL configurations
    @NgModule({
      declarations: [
        AppComponent,
        HomeComponent,
        ProfileComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule,
        MsalModule
      ],
      providers: [
        {
          provide: HTTP_INTERCEPTORS,
          useClass: MsalInterceptor,
          multi: true
        },
        {
          provide: MSAL_INSTANCE,
          useFactory: MSALInstanceFactory
        },
        {
          provide: MSAL_GUARD_CONFIG,
          useFactory: MSALGuardConfigFactory
        },
        {
          provide: MSAL_INTERCEPTOR_CONFIG,
          useFactory: MSALInterceptorConfigFactory
        },
        MsalService,
        MsalGuard,
        MsalBroadcastService
      ],
      bootstrap: [AppComponent, MsalRedirectComponent]
    })
    export class AppModule { }
    

    이 코드는 사용자 인증 및 API 보호를 위해 MSAL을 설정합니다. 인증을 위한 주요 구성 요소 및 MsalInterceptorMsalGuard 서비스를 정의하면서 API 요청을 보호하고 경로를 보호하도록 앱을 구성합니다. 다음 값을 Microsoft Entra 관리 센터의 값으로 바꿉니다.

    • 앱 등록의 Enter_the_Application_Id_HereApplication (client) ID으로 교체합니다.
    • 앱 등록의 Directory (tenant) IDEnter_the_Tenant_Info_Here를 바꾸세요.
  2. 파일을 저장합니다.

애플리케이션에 인증 코드 추가

이 섹션에서는 사용자 인증 및 세션 관리를 처리하는 인증 코드를 애플리케이션에 추가합니다. 테넌트 유형에 따라 적절한 탭을 선택합니다.

  1. 파일을 열고 src/app/app.component.ts 내용을 다음 코드로 바꿉니다.

    // Required for Angular
    import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
    
    // Required for MSAL
    import { MsalService, MsalBroadcastService, MSAL_GUARD_CONFIG, MsalGuardConfiguration } from '@azure/msal-angular';
    import { EventMessage, EventType, InteractionStatus, RedirectRequest } from '@azure/msal-browser';
    
    // Required for RJXS
    import { Subject } from 'rxjs';
    import { filter, takeUntil } from 'rxjs/operators';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html'
    })
    export class AppComponent implements OnInit, OnDestroy {
      title = 'Angular - MSAL Example';
      loginDisplay = false;
      tokenExpiration: string = '';
      private readonly _destroying$ = new Subject<void>();
    
      constructor(
        @Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration,
        private authService: MsalService,
        private msalBroadcastService: MsalBroadcastService
      ) { }
    
      // On initialization of the page, display the page elements based on the user state
      ngOnInit(): void {
        this.msalBroadcastService.inProgress$
            .pipe(
            filter((status: InteractionStatus) => status === InteractionStatus.None),
            takeUntil(this._destroying$)
          )
          .subscribe(() => {
            this.setLoginDisplay();
          });
    
          // Used for storing and displaying token expiration
          this.msalBroadcastService.msalSubject$.pipe(filter((msg: EventMessage) => msg.eventType === EventType.ACQUIRE_TOKEN_SUCCESS)).subscribe(msg => {
          this.tokenExpiration=  (msg.payload as any).expiresOn;
          localStorage.setItem('tokenExpiration', this.tokenExpiration);
        });
      }
    
      // If the user is logged in, present the user with a "logged in" experience
      setLoginDisplay() {
        this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
      }
    
      // Log the user in and redirect them if MSAL provides a redirect URI otherwise go to the default URI
      login() {
        if (this.msalGuardConfig.authRequest) {
          this.authService.loginRedirect({ ...this.msalGuardConfig.authRequest } as RedirectRequest);
        } else {
          this.authService.loginRedirect();
        }
      }
    
      // Log the user out
      logout() {
        this.authService.logoutRedirect();
      }
    
      ngOnDestroy(): void {
        this._destroying$.next(undefined);
        this._destroying$.complete();
      }
    }
    

    이 코드는 MSAL을 Angular와 통합하여 사용자 인증을 관리합니다. 로그인 상태 변경을 수신 대기하고, 로그인 상태를 표시하고, 토큰 획득 이벤트를 처리하며, Microsoft Entra 구성에 따라 사용자를 로그인 또는 로그아웃하는 메서드를 제공합니다.

  2. 파일을 저장합니다.

다음 단계