From a38faf84e73dac7808d0086965f8f3082ab66357 Mon Sep 17 00:00:00 2001
From: pmaytak <34331512+pmaytak@users.noreply.github.com>
Date: Wed, 8 Jul 2020 22:50:49 -0700
Subject: [PATCH 1/4] Update TodoList-WebApi.csproj
---
2-Call-OwnApi/TodoList-WebApi/TodoList-WebApi.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/2-Call-OwnApi/TodoList-WebApi/TodoList-WebApi.csproj b/2-Call-OwnApi/TodoList-WebApi/TodoList-WebApi.csproj
index d4d1f4a..21ef9f1 100644
--- a/2-Call-OwnApi/TodoList-WebApi/TodoList-WebApi.csproj
+++ b/2-Call-OwnApi/TodoList-WebApi/TodoList-WebApi.csproj
@@ -8,7 +8,7 @@
-
+
From 05471102388b5c953ef7c7d6b0f0c9f580414317 Mon Sep 17 00:00:00 2001
From: pmaytak <34331512+pmaytak@users.noreply.github.com>
Date: Wed, 8 Jul 2020 23:12:13 -0700
Subject: [PATCH 2/4] Update README.md
---
2-Call-OwnApi/README.md | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/2-Call-OwnApi/README.md b/2-Call-OwnApi/README.md
index 291a7be..d409f3c 100644
--- a/2-Call-OwnApi/README.md
+++ b/2-Call-OwnApi/README.md
@@ -265,7 +265,7 @@ The relevant code for this sample is in the `Program.cs` file, in the `RunAsync(
### TodoList Web API Code
-The relevant code for the Web API is on the `Startup.cs` class. We are using the method `AddProtectWebApiWithMicrosoftIdentityPlatformV2` to configure the Web API to authenticate using bearer tokens, validate them and protect the API from non authorized calls. These are the steps:
+The relevant code for the Web API is on the `Startup.cs` class. We are using the method `AddMicrosoftWebApiAuthentication` to configure the Web API to authenticate using bearer tokens, validate them and protect the API from non authorized calls. These are the steps:
1. Configuring the API to authenticate using bearer tokens
@@ -274,20 +274,17 @@ The relevant code for the Web API is on the `Startup.cs` class. We are using the
// 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' instead of 'roles'
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
- services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
- .AddAzureADBearer(options => configuration.Bind("AzureAd", options));
+ services.AddMicrosoftWebApiAuthentication(Configuration);
- services.Configure(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
+ services.Configure(JwtBearerDefaults.AuthenticationScheme, options =>
{
- configuration.Bind("AzureAd", options);
- options.Authority += "/v2.0";
options.TokenValidationParameters.RoleClaimType = "roles";
});
```
2. Validating the tokens
- The `AadIssuerValidator.GetIssuerValidator` method can be found on `Microsoft.Identity.Web` project.
+ The `AadIssuerValidator.GetIssuerValidator` method can be found in `Microsoft.Identity.Web` project.
```CSharp
options.TokenValidationParameters.ValidAudiences = new string[] { options.Audience, $"api://{options.Audience}" };
@@ -299,16 +296,19 @@ The relevant code for the Web API is on the `Startup.cs` class. We are using the
Only apps that have added the **application role** created on **Azure Portal** for the `TodoList-webapi-daemon-v2`, will contain the claim `roles` on their tokens
```CSharp
+ var tokenValidatedHandler = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
// This check is required to ensure that the Web API only accepts tokens from tenants where it has been consented and provisioned.
if (!context.Principal.Claims.Any(x => x.Type == ClaimConstants.Scope)
- && !context.Principal.Claims.Any(y => y.Type == ClaimConstants.Roles))
+ && !context.Principal.Claims.Any(y => y.Type == ClaimConstants.Scp)
+ && !context.Principal.Claims.Any(y => y.Type == ClaimConstants.Roles)
+ && !context.Principal.Claims.Any(y => y.Type == ClaimConstants.Role))
{
- throw new UnauthorizedAccessException("Neither scope or roles claim were found in the bearer token.");
+ throw new UnauthorizedAccessException(ErrorMessage.NeitherScopeOrRolesClaimFoundInToken);
}
- await Task.FromResult(0);
+ await tokenValidatedHandler(context).ConfigureAwait(false);
};
```
From 4cc8e813f705e35e2a79806ba0c7003e14df5b65 Mon Sep 17 00:00:00 2001
From: pmaytak <34331512+pmaytak@users.noreply.github.com>
Date: Thu, 9 Jul 2020 12:16:21 -0700
Subject: [PATCH 3/4] Update README.md
---
2-Call-OwnApi/README.md | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/2-Call-OwnApi/README.md b/2-Call-OwnApi/README.md
index d409f3c..1da47ca 100644
--- a/2-Call-OwnApi/README.md
+++ b/2-Call-OwnApi/README.md
@@ -265,7 +265,7 @@ The relevant code for this sample is in the `Program.cs` file, in the `RunAsync(
### TodoList Web API Code
-The relevant code for the Web API is on the `Startup.cs` class. We are using the method `AddMicrosoftWebApiAuthentication` to configure the Web API to authenticate using bearer tokens, validate them and protect the API from non authorized calls. These are the steps:
+The relevant code for the Web API is in the `Startup.cs` class. We are using the method `AddMicrosoftWebApiAuthentication` to configure the Web API to authenticate using bearer tokens, validate them and protect the API from non authorized calls. These are the steps:
1. Configuring the API to authenticate using bearer tokens
@@ -284,11 +284,26 @@ The relevant code for the Web API is on the `Startup.cs` class. We are using the
2. Validating the tokens
- The `AadIssuerValidator.GetIssuerValidator` method can be found in `Microsoft.Identity.Web` project.
+ As a result of the above `AddMicrosoftWebApiAuthentication` method, some audience and issuer validation is set up. More information can be found in [Microsoft Identity Web](https://github.com/AzureAD/microsoft-identity-web) project.
```CSharp
- options.TokenValidationParameters.ValidAudiences = new string[] { options.Audience, $"api://{options.Audience}" };
- options.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetIssuerValidator(options.Authority).Validate;
+ if (options.TokenValidationParameters.AudienceValidator == null
+ && options.TokenValidationParameters.ValidAudience == null
+ && options.TokenValidationParameters.ValidAudiences == null)
+ {
+ RegisterValidAudience registerAudience = new RegisterValidAudience();
+ registerAudience.RegisterAudienceValidation(
+ options.TokenValidationParameters,
+ microsoftIdentityOptions.Value);
+ }
+
+ // If the developer registered an IssuerValidator, do not overwrite it
+ if (options.TokenValidationParameters.IssuerValidator == null)
+ {
+ // Instead of using the default validation (validating against a single tenant, as we do in line of business apps),
+ // we inject our own multi-tenant validation logic (which even accepts both v1.0 and v2.0 tokens)
+ options.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetIssuerValidator(options.Authority).Validate;
+ }
```
3. Protecting the Web API
From 48f60e28ba6374a7eba6ccc626ba65cda7ba3fba Mon Sep 17 00:00:00 2001
From: pmaytak <34331512+pmaytak@users.noreply.github.com>
Date: Thu, 9 Jul 2020 15:02:35 -0700
Subject: [PATCH 4/4] Update README.md
---
2-Call-OwnApi/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/2-Call-OwnApi/README.md b/2-Call-OwnApi/README.md
index 1da47ca..1bd1ef2 100644
--- a/2-Call-OwnApi/README.md
+++ b/2-Call-OwnApi/README.md
@@ -320,7 +320,7 @@ The relevant code for the Web API is in the `Startup.cs` class. We are using the
&& !context.Principal.Claims.Any(y => y.Type == ClaimConstants.Roles)
&& !context.Principal.Claims.Any(y => y.Type == ClaimConstants.Role))
{
- throw new UnauthorizedAccessException(ErrorMessage.NeitherScopeOrRolesClaimFoundInToken);
+ throw new UnauthorizedAccessException("Neither scope or roles claim were found in the bearer token.");
}
await tokenValidatedHandler(context).ConfigureAwait(false);