-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
513 additions
and
331 deletions.
There are no files selected for viewing
43 changes: 26 additions & 17 deletions
43
BlazorWithApis/ServiceApi/Controllers/ApiForServiceDataController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,26 @@ | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace ServiceApi.Controllers; | ||
|
||
[Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] | ||
[ApiController] | ||
[Route("[controller]")] | ||
public class ApiForServiceDataController : ControllerBase | ||
{ | ||
[HttpGet] | ||
public IEnumerable<string> Get() | ||
{ | ||
return new List<string> { "app-app Service API data 1", "service API data 2" }; | ||
} | ||
} | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Swashbuckle.AspNetCore.Annotations; | ||
using System.Collections.Generic; | ||
|
||
namespace ServiceApi.Controllers; | ||
|
||
[Authorize(Policy = "ValidateAccessTokenPolicy", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] | ||
[ApiController] | ||
[Route("[controller]")] | ||
[ProducesResponseType(StatusCodes.Status401Unauthorized)] | ||
[ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
[Produces("application/json")] | ||
[SwaggerTag("Service API for demo service data")] | ||
public class ApiForServiceDataController : ControllerBase | ||
{ | ||
[HttpGet] | ||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<string>))] | ||
[SwaggerOperation(OperationId = "Get", Summary = "Gets service data")] | ||
public IEnumerable<string> Get() | ||
{ | ||
return new List<string> { "app-app Service API data 1", "service API data 2" }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 4 additions & 4 deletions
8
BlazorWithApis/ServiceApi/Policies/HasServiceApiRoleRequirement.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
using Microsoft.AspNetCore.Authorization; | ||
|
||
namespace ServiceApi; | ||
|
||
using Microsoft.AspNetCore.Authorization; | ||
|
||
namespace ServiceApi; | ||
|
||
public class HasServiceApiRoleRequirement : IAuthorizationRequirement { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,92 +1,34 @@ | ||
using Microsoft.AspNetCore.Authentication.JwtBearer; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.Identity.Web; | ||
using Microsoft.IdentityModel.Logging; | ||
using Microsoft.OpenApi.Models; | ||
using ServiceApi; | ||
using System.IdentityModel.Tokens.Jwt; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
builder.Services.AddSingleton<IAuthorizationHandler, HasServiceApiRoleHandler>(); | ||
builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration); | ||
builder.Services.AddControllers(); | ||
|
||
builder.Services.AddAuthorization(options => | ||
{ | ||
options.AddPolicy("ValidateAccessTokenPolicy", validateAccessTokenPolicy => | ||
{ | ||
validateAccessTokenPolicy.Requirements.Add(new HasServiceApiRoleRequirement()); | ||
|
||
// Validate id of application for which the token was created | ||
// In this case the UI application | ||
validateAccessTokenPolicy.RequireClaim("azp", "2b50a014-f353-4c10-aace-024f19a55569"); | ||
|
||
// only allow tokens which used "Private key JWT Client authentication" | ||
// // https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens | ||
// Indicates how the client was authenticated. For a public client, the value is "0". | ||
// If client ID and client secret are used, the value is "1". | ||
// If a client certificate was used for authentication, the value is "2". | ||
validateAccessTokenPolicy.RequireClaim("azpacr", "1"); | ||
}); | ||
}); | ||
|
||
builder.Services.AddSwaggerGen(c => | ||
{ | ||
// add JWT Authentication | ||
var securityScheme = new OpenApiSecurityScheme | ||
{ | ||
Name = "JWT Authentication", | ||
Description = "Enter JWT Bearer token **_only_**", | ||
In = ParameterLocation.Header, | ||
Type = SecuritySchemeType.Http, | ||
Scheme = "bearer", // must be lower case | ||
BearerFormat = "JWT", | ||
Reference = new OpenApiReference | ||
{ | ||
Id = JwtBearerDefaults.AuthenticationScheme, | ||
Type = ReferenceType.SecurityScheme | ||
} | ||
}; | ||
c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme); | ||
c.AddSecurityRequirement(new OpenApiSecurityRequirement | ||
{ | ||
{securityScheme, Array.Empty<string>()} | ||
}); | ||
|
||
c.SwaggerDoc("v1", new OpenApiInfo | ||
{ | ||
Title = "Service API One", | ||
Version = "v1", | ||
Description = "User API One", | ||
Contact = new OpenApiContact | ||
{ | ||
Name = "damienbod", | ||
Email = string.Empty, | ||
Url = new Uri("https://damienbod.com/"), | ||
}, | ||
}); | ||
}); | ||
var app = builder.Build(); | ||
|
||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); | ||
IdentityModelEventSource.ShowPII = true; | ||
JwtSecurityTokenHandler.DefaultMapInboundClaims = false; | ||
|
||
app.UseSwagger(); | ||
app.UseSwaggerUI(c => | ||
{ | ||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Service API One"); | ||
c.RoutePrefix = string.Empty; | ||
}); | ||
|
||
app.UseHttpsRedirection(); | ||
|
||
app.UseRouting(); | ||
|
||
app.UseAuthentication(); | ||
app.UseAuthorization(); | ||
|
||
app.MapControllers(); | ||
|
||
app.Run(); | ||
using Microsoft.AspNetCore.Builder; | ||
using Serilog; | ||
using ServiceApi; | ||
using System; | ||
|
||
Log.Logger = new LoggerConfiguration() | ||
.WriteTo.Console() | ||
.CreateBootstrapLogger(); | ||
|
||
Log.Information("Starting ServiceApi application"); | ||
|
||
try | ||
{ | ||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
builder.Host.UseSerilog((context, loggerConfiguration) => loggerConfiguration | ||
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}") | ||
.ReadFrom.Configuration(context.Configuration)); | ||
|
||
var app = builder | ||
.ConfigureServices() | ||
.ConfigurePipeline(); | ||
|
||
app.Run(); | ||
} | ||
catch (Exception ex) when (ex.GetType().Name is not "StopTheHostException" && ex.GetType().Name is not "HostAbortedException") | ||
{ | ||
Log.Fatal(ex, "Unhandled exception"); | ||
} | ||
finally | ||
{ | ||
Log.Information("Shut down complete"); | ||
Log.CloseAndFlush(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
{ | ||
"profiles": { | ||
"ServiceApi": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"launchUrl": "", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"applicationUrl": "https://localhost:44324" | ||
} | ||
} | ||
{ | ||
"profiles": { | ||
"ServiceApi": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"launchUrl": "", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"applicationUrl": "https://localhost:44324" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using Microsoft.AspNetCore.Builder; | ||
|
||
namespace ServiceApi; | ||
|
||
public static class SecurityHeadersDefinitions | ||
{ | ||
public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev) | ||
{ | ||
var policy = new HeaderPolicyCollection() | ||
.AddFrameOptionsDeny() | ||
.AddContentTypeOptionsNoSniff() | ||
.AddReferrerPolicyStrictOriginWhenCrossOrigin() | ||
.RemoveServerHeader() | ||
.AddCrossOriginOpenerPolicy(builder => builder.SameOrigin()) | ||
.AddCrossOriginEmbedderPolicy(builder => builder.RequireCorp()) | ||
.AddCrossOriginResourcePolicy(builder => builder.SameOrigin()) | ||
.AddContentSecurityPolicy(builder => | ||
{ | ||
builder.AddObjectSrc().None(); | ||
builder.AddBlockAllMixedContent(); | ||
builder.AddImgSrc().Self().From("data:"); | ||
builder.AddFormAction().Self(); | ||
builder.AddFontSrc().Self(); | ||
builder.AddStyleSrc().Self(); | ||
builder.AddBaseUri().Self(); | ||
builder.AddScriptSrc().WithNonce(); | ||
builder.AddFrameAncestors().None(); | ||
}) | ||
.AddPermissionsPolicy(builder => | ||
{ | ||
builder.AddAccelerometer().None(); | ||
builder.AddAutoplay().None(); | ||
builder.AddCamera().None(); | ||
builder.AddEncryptedMedia().None(); | ||
builder.AddFullscreen().All(); | ||
builder.AddGeolocation().None(); | ||
builder.AddGyroscope().None(); | ||
builder.AddMagnetometer().None(); | ||
builder.AddMicrophone().None(); | ||
builder.AddMidi().None(); | ||
builder.AddPayment().None(); | ||
builder.AddPictureInPicture().None(); | ||
builder.AddSyncXHR().None(); | ||
builder.AddUsb().None(); | ||
}); | ||
|
||
if (!isDev) | ||
{ | ||
// maxage = one year in seconds | ||
policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365); | ||
} | ||
|
||
policy.ApplyDocumentHeadersToAllResponses(); | ||
|
||
return policy; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<UserSecretsId>196b270c-b0c0-4b90-8f04-d3108e701d51</UserSecretsId> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Identity.Web" Version="2.17.4" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> | ||
</ItemGroup> | ||
|
||
</Project> | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net9.0</TargetFramework> | ||
<UserSecretsId>196b270c-b0c0-4b90-8f04-d3108e701d51</UserSecretsId> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Identity.Web" Version="3.5.0" /> | ||
|
||
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="0.24.0" /> | ||
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders.TagHelpers" Version="0.24.0" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" /> | ||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="7.2.0" /> | ||
|
||
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.2" /> | ||
<PackageReference Include="Azure.Identity" Version="1.13.1" /> | ||
|
||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" /> | ||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" /> | ||
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" /> | ||
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" /> | ||
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" /> | ||
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.