diff --git a/README.md b/README.md
index 58f0102..c898906 100644
--- a/README.md
+++ b/README.md
@@ -154,6 +154,33 @@ Data Source=127.0.0.1,1433;Initial Catalog=Cachorro;User Id=sa;Password=Abcd1234
```
+# Azure Entra ID
+
+```
+
+https://learn.microsoft.com/en-us/entra/identity-platform/v2-overview
+```
+
+```
+https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app
+```
+
+```
+https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc
+```
+
+```
+
+https://learn.microsoft.com/en-us/entra/identity-platform/scenario-protected-web-api-app-configuration?tabs=aspnetcore#bearer-token
+
+```
+
+```
+
+https://learn.microsoft.com/en-us/entra/identity-platform/scenario-web-app-sign-user-app-configuration?tabs=aspnet
+
+```
+
diff --git a/src/DEPLOY.Cachorro.Api/Controllers/v1/CachorrosController.cs b/src/DEPLOY.Cachorro.Api/Controllers/v1/CachorrosController.cs
index 4ca1cbe..39865c4 100644
--- a/src/DEPLOY.Cachorro.Api/Controllers/v1/CachorrosController.cs
+++ b/src/DEPLOY.Cachorro.Api/Controllers/v1/CachorrosController.cs
@@ -1,5 +1,6 @@
using Asp.Versioning;
using DEPLOY.Cachorro.Repository;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Swashbuckle.AspNetCore.Annotations;
@@ -9,6 +10,7 @@ namespace DEPLOY.Cachorro.Api.Controllers.v1
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
+ [Authorize]
public class CachorrosController : ControllerBase
{
public readonly CachorroDbContext _context;
diff --git a/src/DEPLOY.Cachorro.Api/Extensions/Auth/AuthExtension.cs b/src/DEPLOY.Cachorro.Api/Extensions/Auth/AuthExtension.cs
new file mode 100644
index 0000000..6fb429a
--- /dev/null
+++ b/src/DEPLOY.Cachorro.Api/Extensions/Auth/AuthExtension.cs
@@ -0,0 +1,20 @@
+using Azure.Identity;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.Extensions.Azure;
+using Microsoft.Identity.Web;
+using System.Diagnostics.CodeAnalysis;
+
+namespace DEPLOY.Cachorro.Api.Extensions.Auth
+{
+ [ExcludeFromCodeCoverage]
+ public static class AuthExtension
+ {
+ public static void AddAuthExtension(
+ this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ .AddMicrosoftIdentityWebApi(configuration.GetSection("AzureAd"));
+ }
+ }
+}
diff --git a/src/DEPLOY.Cachorro.Api/Extensions/KeyVault/KeyVaultExtension.cs b/src/DEPLOY.Cachorro.Api/Extensions/KeyVault/KeyVaultExtension.cs
index ccc6cac..4ce7b51 100644
--- a/src/DEPLOY.Cachorro.Api/Extensions/KeyVault/KeyVaultExtension.cs
+++ b/src/DEPLOY.Cachorro.Api/Extensions/KeyVault/KeyVaultExtension.cs
@@ -7,8 +7,8 @@ namespace DEPLOY.Cachorro.Api.Extensions.KeyVault
[ExcludeFromCodeCoverage]
public static class KeyVaultExtension
{
- public static IServiceCollection AddKeyVaultExtension(
- this IServiceCollection services,
+ public static void AddKeyVaultExtension(
+ this IServiceCollection services,
IConfiguration configuration)
{
services.AddAzureClients(clientBuilder =>
@@ -18,8 +18,6 @@ public static IServiceCollection AddKeyVaultExtension(
clientBuilder.UseCredential(new DefaultAzureCredential());
});
-
- return services;
}
}
}
diff --git a/src/DEPLOY.Cachorro.Api/Extensions/Swagger/ConfigureSwaggerOptions.cs b/src/DEPLOY.Cachorro.Api/Extensions/Swagger/ConfigureSwaggerOptions.cs
index 0515567..abb84f0 100644
--- a/src/DEPLOY.Cachorro.Api/Extensions/Swagger/ConfigureSwaggerOptions.cs
+++ b/src/DEPLOY.Cachorro.Api/Extensions/Swagger/ConfigureSwaggerOptions.cs
@@ -1,5 +1,6 @@
using Asp.Versioning;
using Asp.Versioning.ApiExplorer;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
@@ -12,6 +13,8 @@ namespace DEPLOY.Cachorro.Api.Extensions.Swagger
[ExcludeFromCodeCoverage]
public class ConfigureSwaggerOptions : IConfigureOptions
{
+ public const string AuthenticationScheme = "JWT";
+ public const string HeaderName = "Authorization";
private readonly IApiVersionDescriptionProvider provider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider;
@@ -22,6 +25,31 @@ public void Configure(SwaggerGenOptions options)
{
options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
}
+
+ options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
+ {
+ Name = ConfigureSwaggerOptions.HeaderName,
+ In = ParameterLocation.Header,
+ Description = "Informe o token JWT com Bearer no formato: Bearer {token}",
+ Type = SecuritySchemeType.ApiKey,
+ BearerFormat = ConfigureSwaggerOptions.AuthenticationScheme,
+ Scheme = JwtBearerDefaults.AuthenticationScheme
+ });
+
+ options.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = JwtBearerDefaults.AuthenticationScheme
+ }
+ },
+ new string[]{}
+ }
+ });
}
private static OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description)
diff --git a/src/DEPLOY.Cachorro.Api/Program.cs b/src/DEPLOY.Cachorro.Api/Program.cs
index bba595c..732fd77 100644
--- a/src/DEPLOY.Cachorro.Api/Program.cs
+++ b/src/DEPLOY.Cachorro.Api/Program.cs
@@ -3,6 +3,7 @@
using DEPLOY.Cachorro.Api.Extensions.KeyVault;
using DEPLOY.Cachorro.Api.Extensions.Swagger;
using DEPLOY.Cachorro.Api.Extensions.Telemetria;
+using DEPLOY.Cachorro.Api.Extensions.Auth;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
@@ -15,10 +16,15 @@ public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
+ builder.Services.AddAuthExtension(builder.Configuration);
+
builder.Services.AddControllers()
.AddJsonOptions(opt =>
{
opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
+ opt.JsonSerializerOptions.WriteIndented = true;
+ opt.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
+
});
builder.Services.AddRouting(opt =>
@@ -34,7 +40,7 @@ public static void Main(string[] args)
builder.Logging.AddLogExtension(builder.Configuration);
builder.Services.AddDatabaseExtension(builder.Configuration);
builder.Services.AddTelemetriaExtension(builder.Configuration);
- builder.Services.AddSwaggerExtension();
+ builder.Services.AddSwaggerExtension();
builder.Configuration.AddAppConfigurationExtension(builder.Services);
var app = builder.Build();
@@ -44,6 +50,7 @@ public static void Main(string[] args)
app.UseHttpsRedirection();
+ app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
diff --git a/src/DEPLOY.Cachorro.Api/appsettings.json b/src/DEPLOY.Cachorro.Api/appsettings.json
index 9dd5923..4d84ab5 100644
--- a/src/DEPLOY.Cachorro.Api/appsettings.json
+++ b/src/DEPLOY.Cachorro.Api/appsettings.json
@@ -27,5 +27,10 @@
"maxDelay": 2,
"maxRetries": 10
}
+ },
+ "AzureAd": {
+ "Instance": "",
+ "ClientId": "",
+ "TenantId": ""
}
-}
\ No newline at end of file
+}