Merge pull request #260 from meysamhadeli/fix/fix-scope-validation-in-apis

fix: Fix scope validation in claims for all endpoints
This commit is contained in:
Meysam Hadeli 2023-05-19 02:44:50 +03:30 committed by GitHub
commit f6639d772f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 52 additions and 25 deletions

View File

@ -20,9 +20,6 @@ public static class ServiceCollectionExtensions
IConfiguration configuration,
params Assembly[] assemblies)
{
// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/openapi
services.AddEndpointsApiExplorer();
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
services.AddOptions<SwaggerOptions>().Bind(configuration.GetSection(nameof(SwaggerOptions)))
.ValidateDataAnnotations();
@ -41,20 +38,30 @@ public static class ServiceCollectionExtensions
options.AddEnumsWithValuesFixFilters();
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
BearerFormat = "JWT",
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference {Type = ReferenceType.SecurityScheme, Id = "Bearer"},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header
Reference = new OpenApiReference
{
Type=ReferenceType.SecurityScheme,
Id="Bearer"
}
},
new List<string>()
new string[]{}
}
});
options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
////https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/467
@ -65,7 +72,7 @@ public static class ServiceCollectionExtensions
// options.EnableAnnotations();
});
services.Configure<SwaggerGeneratorOptions>(o => o.InferSecuritySchemes = true);
// services.Configure<SwaggerGeneratorOptions>(o => o.InferSecuritySchemes = true);
static string XmlCommentsFilePath(Assembly assembly)
{

View File

@ -60,7 +60,9 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
var claims =
new Dictionary<string, object>
{
{ ClaimTypes.Name, "test@sample.com" }, { ClaimTypes.Role, "admin" },
{ ClaimTypes.Name, "test@sample.com" },
{ ClaimTypes.Role, "admin" },
{"scope", "flight-api"}
};
var httpClient = _factory?.CreateClient();
httpClient.SetFakeBearerToken(claims);

View File

@ -7,6 +7,7 @@ using BuildingBlocks.Core.Event;
using BuildingBlocks.Core.Model;
using BuildingBlocks.EventStoreDB.Repository;
using BuildingBlocks.Web;
using Duende.IdentityServer.EntityFramework.Entities;
using Elasticsearch.Net;
using Exceptions;
using Flight;
@ -50,7 +51,7 @@ public class CreateBookingEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("CreateBooking")
.WithApiVersionSet(builder.NewApiVersionSet("Booking").Build())
.Produces<CreateBookingResponseDto>()

View File

@ -60,6 +60,7 @@ public static class InfrastructureExtensions
builder.Services.AddPersistMessageProcessor(env);
builder.Services.AddMongoDbContext<BookingReadDbContext>(configuration);
builder.Services.AddEndpointsApiExplorer();
builder.AddCustomSerilog(env);
builder.Services.AddJwt();
builder.Services.AddHttpContextAccessor();

View File

@ -10,6 +10,7 @@ using BuildingBlocks.Web;
using Exceptions;
using Models;
using Data;
using Duende.IdentityServer.EntityFramework.Entities;
using FluentValidation;
using MapsterMapper;
using MassTransit;
@ -50,7 +51,7 @@ public class CreateAircraftEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("CreateAircraft")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<CreateAircraftResponseDto>()

View File

@ -9,6 +9,7 @@ using BuildingBlocks.Core.Event;
using BuildingBlocks.Web;
using Exceptions;
using Data;
using Duende.IdentityServer.EntityFramework.Entities;
using FluentValidation;
using MapsterMapper;
using MassTransit;
@ -48,7 +49,7 @@ public class CreateAirportEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("CreateAirport")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<CreateAirportResponseDto>()

View File

@ -67,6 +67,7 @@ public static class InfrastructureExtensions
builder.Services.AddMongoDbContext<FlightReadDbContext>(configuration);
builder.Services.AddPersistMessageProcessor(env);
builder.Services.AddEndpointsApiExplorer();
builder.AddCustomSerilog(env);
builder.Services.AddJwt();
builder.Services.AddCustomSwagger(configuration, typeof(FlightRoot).Assembly);

View File

@ -8,6 +8,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Core.Event;
using BuildingBlocks.Web;
using Data;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using FluentValidation;
using MapsterMapper;
@ -54,7 +55,7 @@ public class CreateFlightEndpoint : IMinimalEndpoint
return Results.CreatedAtRoute("GetFlightById", new { id = result.Id }, response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("CreateFlight")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<CreateFlightResponseDto>(StatusCodes.Status201Created)

View File

@ -8,6 +8,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Core.Event;
using BuildingBlocks.Web;
using Data;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using FluentValidation;
using MediatR;
@ -35,7 +36,7 @@ public class DeleteFlightEndpoint : IMinimalEndpoint
return Results.NoContent();
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("DeleteFlight")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces(StatusCodes.Status204NoContent)

View File

@ -11,6 +11,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Web;
using Data;
using Dtos;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using MapsterMapper;
using MediatR;
@ -42,8 +43,7 @@ public class GetAvailableFlightsEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.WithOpenApi()
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("GetAvailableFlights")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<GetAvailableFlightsResponseDto>()

View File

@ -8,6 +8,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Web;
using Data;
using Dtos;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using FluentValidation;
using MapsterMapper;
@ -37,7 +38,7 @@ public class GetFlightByIdEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("GetFlightById")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<GetFlightByIdResponseDto>()

View File

@ -9,6 +9,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Core.Event;
using BuildingBlocks.Web;
using Data;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using Flight.Flights.Features.CreatingFlight.V1;
using FluentValidation;
@ -52,7 +53,7 @@ public class UpdateFlightEndpoint : IMinimalEndpoint
return Results.NoContent();
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("UpdateFlight")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces(StatusCodes.Status204NoContent)

View File

@ -23,6 +23,7 @@ public class RegisterNewUserConsumerHandler : IConsumer<UserCreated>
public Task Consume(ConsumeContext<UserCreated> context)
{
_logger.LogInformation($"this is a test consumer for {nameof(UserCreated).Underscore()} in {_options.Name}");
_logger.LogInformation($"we got this message: {context?.Message}");
return Task.CompletedTask;
}
}

View File

@ -7,6 +7,7 @@ using Ardalis.GuardClauses;
using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Core.Event;
using BuildingBlocks.Web;
using Duende.IdentityServer.EntityFramework.Entities;
using Flight.Data;
using Flight.Seats.Exceptions;
using Flight.Seats.Models;
@ -40,7 +41,7 @@ public class CreateSeatEndpoint : IMinimalEndpoint
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
{
builder.MapPost($"{EndpointConfig.BaseApiPath}/flight/seat", CreateSeat)
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("CreateSeat")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<CreateSeatResponseDto>()

View File

@ -10,6 +10,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Web;
using Data;
using Dtos;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using FluentValidation;
using MapsterMapper;
@ -30,7 +31,7 @@ public class GetAvailableSeatsEndpoint : IMinimalEndpoint
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
{
builder.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-seats/{{id}}", GetAvailableSeats)
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("GetAvailableSeats")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<GetAvailableSeatsResponseDto>()

View File

@ -8,6 +8,7 @@ using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Core.Event;
using BuildingBlocks.Web;
using Data;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using FluentValidation;
using MapsterMapper;
@ -33,7 +34,7 @@ public class ReserveSeatEndpoint : IMinimalEndpoint
public IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder)
{
builder.MapPost($"{EndpointConfig.BaseApiPath}/flight/reserve-seat", ReserveSeat)
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("ReserveSeat")
.WithApiVersionSet(builder.NewApiVersionSet("Flight").Build())
.Produces<ReserveSeatResponseDto>()

View File

@ -59,7 +59,7 @@ public static class Config
Constants.StandardScopes.FlightApi,
Constants.StandardScopes.PassengerApi,
Constants.StandardScopes.BookingApi,
new(Constants.StandardScopes.IdentityApi)
Constants.StandardScopes.IdentityApi
}
}
};

View File

@ -58,6 +58,7 @@ public static class InfrastructureExtensions
}));
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddControllers();
builder.Services.AddPersistMessageProcessor(env);
builder.Services.AddCustomDbContext<IdentityContext>();

View File

@ -9,6 +9,7 @@ using BuildingBlocks.Contracts.EventBus.Messages;
using BuildingBlocks.Core;
using BuildingBlocks.Core.CQRS;
using BuildingBlocks.Web;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using FluentValidation;
using MapsterMapper;

View File

@ -64,6 +64,7 @@ public static class InfrastructureExtensions
builder.AddCustomSerilog(env);
builder.Services.AddJwt();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddCustomSwagger(configuration, typeof(PassengerRoot).Assembly);
builder.Services.AddCustomVersioning();
builder.Services.AddCustomMediatR();

View File

@ -10,6 +10,7 @@ using MapsterMapper;
using Microsoft.EntityFrameworkCore;
using Data;
using Dtos;
using Duende.IdentityServer.EntityFramework.Entities;
using MassTransit;
using MediatR;
using Microsoft.AspNetCore.Builder;
@ -48,7 +49,7 @@ public class CompleteRegisterPassengerEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("CompleteRegisterPassenger")
.WithApiVersionSet(builder.NewApiVersionSet("Passenger").Build())
.Produces<CompleteRegisterPassengerResponseDto>()

View File

@ -7,6 +7,7 @@ using FluentValidation;
using MapsterMapper;
using Ardalis.GuardClauses;
using BuildingBlocks.Web;
using Duende.IdentityServer.EntityFramework.Entities;
using Exceptions;
using MediatR;
using Microsoft.AspNetCore.Builder;
@ -34,7 +35,7 @@ public class GetPassengerByIdEndpoint : IMinimalEndpoint
return Results.Ok(response);
})
.RequireAuthorization()
.RequireAuthorization(nameof(ApiScope))
.WithName("GetPassengerById")
.WithApiVersionSet(builder.NewApiVersionSet("Passenger").Build())
.Produces<GetPassengerByIdResponseDto>()