Introduction
In this article, we will integrate the Azure Active Directory into an Angular application and get data from a secured web API using a JWT bearer token. There will be 3 steps to integrate the Azure Active Directory into our application.
- const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;
- @NgModule({
- declarations: [
- AppComponent,
- ProfileComponent
- ],
- imports: [
- BrowserModule,
- AppRoutingModule,
- HttpClientModule,
- MsalModule.forRoot({
- auth: {
- clientId: environment.clientId,
- authority: environment.authority,
- redirectUri: environment.redirectUrl,
- postLogoutRedirectUri: environment.postLogoutRedirectUri,
- navigateToLoginRequestUrl: true
- }, cache: {
- cacheLocation: 'localStorage',
- storeAuthStateInCookie: isIE,
- },
- }, {
- popUp: !isIE,
- consentScopes: [
- 'user.read',
- 'openid',
- 'profile',
- ],
- protectedResourceMap: [
- ['https://graph.microsoft.com/v1.0/me', ['user.read']]
- ]
- }),
- ],
- providers: [
- {
- provide: LocationStrategy,
- useClass: HashLocationStrategy
- },
- {
- provide: HTTP_INTERCEPTORS,
- useClass: MsalInterceptor,
- multi: true
- },
- MsalService,
- ApiService
- ],
- bootstrap: [AppComponent]
- })
In your app-routing.module.ts file, add the following line:
- const routes: Routes = [
- {
- path: '',
- component: ProfileComponent,
- canActivate: [MsalGuard]
- }
- ];
-
- @NgModule({
- imports: [RouterModule.forRoot(routes)],
- exports: [RouterModule]
- })
Create a new component called profile.
Create a new service in the called api.service.ts into an app/shared folder and add the following code:
- @Injectable({ providedIn: 'root' })
- export class ApiService {
-
- private baseUrl = environment.apiEndpoint;
- constructor(private http: HttpClient) { }
-
- getWeathers(): Observable<IWeatherForecast[]> {
-
- const reqHeader = new HttpHeaders({
- 'Content-Type': 'application/json',
- Authorization: 'Bearer ' + localStorage.getItem('msal.idtoken')
- });
- return this.http.get<IWeatherForecast[]>(this.baseUrl + 'home', { headers: reqHeader }).pipe(
- retry(1),
- catchError(this.errorHandl)
- );
- }
-
- errorHandl(error) {
- let errorMessage = '';
- if (error.error instanceof ErrorEvent) {
- errorMessage = error.error.message;
- } else {
- errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
- }
- return throwError(errorMessage);
- }
- }
In your newly created component, please add the following lines of code:
- export class ProfileComponent implements OnInit {
-
- name: string;
- username: string;
-
- public weatherData: IWeatherForecast[] = [];
-
- constructor(private msalService: MsalService, private apiService: ApiService) { }
-
- ngOnInit(): void {
- const account = this.msalService.getAccount();
- this.name = account.name;
- this.username = account.userName;
-
- this.getWeatherinformation();
- }
-
- getWeatherinformation() {
- this.apiService.getWeathers().subscribe(res => {
-
- this.weatherData = res as IWeatherForecast[];
- });
- }
-
-
- logout() {
- localStorage.clear();
- this.msalService.logout();
- }
- }
In your profile.component.html, please add the following code:
- Name: {{name}}<br/>
- Username: {{username}}
- <br/>
-
- <h3>Data From Web API</h3>
- <ul>
- <li *ngFor="let element of weatherData" [type]="element">
- {{element.date}}, {{element.summary}}, {{element.temperatureC}}, {{element.temperatureF}}
- </li>
- </ul>
- <button type='button' name='logOut' id='logout' (click)="logout()">Log Out</button>
- The client application is ready.
- Create a Web API project:
- After creating your API project, please add the following package:
- Microsoft.AspNetCore.Authentication.JwtBearer
-
- Microsoft.AspNetCore.Cors
- Add the following code into the Startup.cs file:
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
-
-
- services.AddCors(o => o.AddPolicy("default", builder =>
- {
- builder.AllowAnyOrigin()
- .AllowAnyMethod()
- .AllowAnyHeader();
- }));
-
- services.AddAuthentication(o =>
- {
- o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
- o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
- o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
- }).AddJwtBearer(opt =>
- {
- opt.IncludeErrorDetails = true;
- opt.Authority = "https://login.microsoftonline.com/c1ec3067-d41e-4053-b90c-d7619dae7650/v2.0";
- opt.Audience = "b9535469-bbe7-4a66-8823-4fef098be78e";
- });
- }
-
-
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
-
- app.UseCors("default");
- app.UseRouting();
-
- app.UseAuthentication();
- app.UseAuthorization();
-
- app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
- }
- Add a Controller and add the following code into that controller:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Logging;
-
- namespace azure_ad_webapi.Controllers
- {
- [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
- [Route("api/home")]
- [Consumes("application/json")]
- [Produces("application/json")]
- [ApiController]
- public class HomeController : ControllerBase
- {
- private static readonly string[] Summaries =
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
-
-
- public HomeController()
- {
-
- }
-
- [HttpGet]
- public IEnumerable<WeatherForecast> Get()
- {
- var rng = new Random();
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateTime.Now.AddDays(index),
- TemperatureC = rng.Next(-20, 55),
- Summary = Summaries[rng.Next(Summaries.Length)]
- })
- .ToArray();
- }
- }
- }
All code is hosted in
GitHub. You can check it for a better understanding.