From e1fc28be8b46274d910f29331d1e181f4ae6b094 Mon Sep 17 00:00:00 2001 From: Tarun Jain Date: Fri, 31 Mar 2023 23:26:34 +0530 Subject: [PATCH] add .editorconfigfiles --- .../Ordering/Ordering.API/.editorconfig | 132 +++++++++ .../Ordering/Ordering.API/Ordering.API.csproj | 4 + src/Services/Ordering/Ordering.API/Program.cs | 265 ++++++++++-------- 3 files changed, 291 insertions(+), 110 deletions(-) create mode 100644 src/Services/Ordering/Ordering.API/.editorconfig diff --git a/src/Services/Ordering/Ordering.API/.editorconfig b/src/Services/Ordering/Ordering.API/.editorconfig new file mode 100644 index 000000000..a2816621e --- /dev/null +++ b/src/Services/Ordering/Ordering.API/.editorconfig @@ -0,0 +1,132 @@ +############################### +# Core EditorConfig Options # +############################### +root = true +# All files +[*] +indent_style = space + +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 +insert_final_newline = true +charset = utf-8-bom +############################### +# .NET Coding Conventions # +############################### +[*.{cs,vb}] +# Organize usings +dotnet_sort_system_directives_first = true +# this. preferences +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_readonly_field = true:suggestion +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +############################### +# Naming Conventions # +############################### +# Style Definitions +dotnet_naming_style.pascal_case_style.capitalization = pascal_case +# Use PascalCase for constant fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_symbols.constant_fields.required_modifiers = const +############################### +# C# Coding Conventions # +############################### +[*.cs] +# var preferences +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:silent +csharp_style_var_elsewhere = true:silent +# Expression-bodied members +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +# Pattern matching preferences +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +# Null-checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion +# Expression-level preferences +csharp_prefer_braces = true:silent +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +############################### +# C# Formatting Rules # +############################### +# New line preferences +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true +# Indentation preferences +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = flush_left +# Space preferences +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_around_binary_operators = before_and_after +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +# Wrapping preferences +csharp_preserve_single_line_statements = true +csharp_preserve_single_line_blocks = true +############################### +# VB Coding Conventions # +############################### +[*.vb] +# Modifier preferences +visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj index 573ce2665..166685321 100644 --- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj +++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj @@ -76,4 +76,8 @@ + + + + diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 632bc37af..ba62a4dcc 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -4,77 +4,79 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; var appName = "Ordering.API"; -var builder = WebApplication.CreateBuilder(new WebApplicationOptions { +var builder = WebApplication.CreateBuilder(new WebApplicationOptions +{ Args = args, ApplicationName = typeof(Program).Assembly.FullName, ContentRootPath = Directory.GetCurrentDirectory() }); -if (builder.Configuration.GetValue("UseVault", false)) { +if (builder.Configuration.GetValue("UseVault", false)) +{ TokenCredential credential = new ClientSecretCredential( builder.Configuration["Vault:TenantId"], builder.Configuration["Vault:ClientId"], builder.Configuration["Vault:ClientSecret"]); builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); } - - - - builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); builder.Configuration.AddEnvironmentVariables(); -builder.WebHost.ConfigureKestrel(options => { +builder.WebHost.ConfigureKestrel(options => +{ var ports = GetDefinedPorts(builder.Configuration); - options.Listen(IPAddress.Any, ports.httpPort, listenOptions => { + options.Listen(IPAddress.Any, ports.httpPort, listenOptions => + { listenOptions.Protocols = HttpProtocols.Http1AndHttp2; }); - options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => { + options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => + { listenOptions.Protocols = HttpProtocols.Http2; }); }); builder.WebHost.CaptureStartupErrors(false); builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); - builder.Services - .AddGrpc(options => { - options.EnableDetailedErrors = true; - }) - .Services - .AddApplicationInsights(builder.Configuration) - .AddCustomMvc() - .AddHealthChecks(builder.Configuration) - .AddCustomDbContext(builder.Configuration) - .AddCustomSwagger(builder.Configuration) - .AddCustomAuthentication(builder.Configuration) - .AddCustomAuthorization(builder.Configuration) - .AddCustomIntegrations(builder.Configuration) - .AddCustomConfiguration(builder.Configuration) - .AddEventBus(builder.Configuration); + .AddGrpc(options => + { + options.EnableDetailedErrors = true; + }) + .Services + .AddApplicationInsights(builder.Configuration) + .AddCustomMvc() + .AddHealthChecks(builder.Configuration) + .AddCustomDbContext(builder.Configuration) + .AddCustomSwagger(builder.Configuration) + .AddCustomAuthentication(builder.Configuration) + .AddCustomAuthorization(builder.Configuration) + .AddCustomIntegrations(builder.Configuration) + .AddCustomConfiguration(builder.Configuration) + .AddEventBus(builder.Configuration); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); - // Register your own things directly with Autofac here. Don't // call builder.Populate(), that happens in AutofacServiceProviderFactory // for you. builder.Host.ConfigureContainer(conbuilder => conbuilder.RegisterModule(new MediatorModule())); builder.Host.ConfigureContainer(conbuilder => conbuilder.RegisterModule(new ApplicationModule(builder.Configuration["ConnectionString"]))); - var app = builder.Build(); -if (app.Environment.IsDevelopment()) { +if (app.Environment.IsDevelopment()) +{ app.UseDeveloperExceptionPage(); } -else { +else +{ app.UseExceptionHandler("/Home/Error"); } var pathBase = app.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) { +if (!string.IsNullOrEmpty(pathBase)) +{ app.UsePathBase(pathBase); } - app.UseSwagger() - .UseSwaggerUI(c => { + .UseSwaggerUI(c => + { c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Ordering.API V1"); c.OAuthClientId("orderingswaggerui"); c.OAuthAppName("Ordering Swagger UI"); @@ -84,34 +86,35 @@ app.UseRouting(); app.UseCors("CorsPolicy"); app.UseAuthentication(); app.UseAuthorization(); - app.MapGrpcService(); - app.MapDefaultControllerRoute(); - app.MapControllers(); - app.MapGet("/_proto/", async ctx => +app.MapDefaultControllerRoute(); +app.MapControllers(); +app.MapGet("/_proto/", async ctx => +{ + ctx.Response.ContentType = "text/plain"; + using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read); + using var sr = new StreamReader(fs); + while (!sr.EndOfStream) { - ctx.Response.ContentType = "text/plain"; - using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read); - using var sr = new StreamReader(fs); - while (!sr.EndOfStream) { - var line = await sr.ReadLineAsync(); - if (line != "/* >>" || line != "<< */") { - await ctx.Response.WriteAsync(line); - } + var line = await sr.ReadLineAsync(); + if (line != "/* >>" || line != "<< */") + { + await ctx.Response.WriteAsync(line); } - }); - app.MapHealthChecks("/hc", new HealthCheckOptions() { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - app.MapHealthChecks("/liveness", new HealthCheckOptions { - Predicate = r => r.Name.Contains("self") - }); + } +}); +app.MapHealthChecks("/hc", new HealthCheckOptions() +{ + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse +}); +app.MapHealthChecks("/liveness", new HealthCheckOptions +{ + Predicate = r => r.Name.Contains("self") +}); ConfigureEventBus(app); -try { - Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName); - - +try +{ Log.Information("Applying migrations ({ApplicationContext})...", Program.AppName); using var scope = app.Services.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -129,14 +132,17 @@ try { return 0; } -catch (Exception ex) { +catch (Exception ex) +{ Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); return 1; } -finally { +finally +{ Log.CloseAndFlush(); } -void ConfigureEventBus(IApplicationBuilder app) { +void ConfigureEventBus(IApplicationBuilder app) +{ var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe>(); @@ -146,7 +152,8 @@ void ConfigureEventBus(IApplicationBuilder app) { eventBus.Subscribe>(); eventBus.Subscribe>(); } -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) { +Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) +{ var seqServerUrl = configuration["Serilog:SeqServerUrl"]; var logstashUrl = configuration["Serilog:LogstashgUrl"]; return new LoggerConfiguration() @@ -159,29 +166,30 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) { .ReadFrom.Configuration(configuration) .CreateLogger(); } - - - -(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) { +(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) +{ var grpcPort = config.GetValue("GRPC_PORT", 5001); var port = config.GetValue("PORT", 80); return (port, grpcPort); } - -public partial class Program { +public partial class Program +{ public static string Namespace = typeof(Program).Assembly.GetName().Name; public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); } -static class CustomExtensionsMethods { - public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) { +static class CustomExtensionsMethods +{ + public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) + { services.AddApplicationInsightsTelemetry(configuration); services.AddApplicationInsightsKubernetesEnricher(); return services; } - public static IServiceCollection AddCustomMvc(this IServiceCollection services) { + public static IServiceCollection AddCustomMvc(this IServiceCollection services) + { // Add framework services. services.AddControllers(options => { @@ -191,7 +199,8 @@ static class CustomExtensionsMethods { .AddApplicationPart(typeof(OrdersController).Assembly) .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - services.AddCors(options => { + services.AddCors(options => + { options.AddPolicy("CorsPolicy", builder => builder .SetIsOriginAllowed((host) => true) @@ -203,7 +212,8 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) + { var hcBuilder = services.AddHealthChecks(); hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); @@ -214,7 +224,8 @@ static class CustomExtensionsMethods { name: "OrderingDB-check", tags: new string[] { "orderingdb" }); - if (configuration.GetValue("AzureServiceBusEnabled")) { + if (configuration.GetValue("AzureServiceBusEnabled")) + { hcBuilder .AddAzureServiceBusTopic( configuration["EventBusConnection"], @@ -222,7 +233,8 @@ static class CustomExtensionsMethods { name: "ordering-servicebus-check", tags: new string[] { "servicebus" }); } - else { + else + { hcBuilder .AddRabbitMQ( $"amqp://{configuration["EventBusConnection"]}", @@ -233,11 +245,13 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) { + public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) + { services.AddDbContext(options => { options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => { + sqlServerOptionsAction: sqlOptions => + { sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }); @@ -245,9 +259,11 @@ static class CustomExtensionsMethods { ServiceLifetime.Scoped //Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request) ); - services.AddDbContext(options => { + services.AddDbContext(options => + { options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => { + sqlServerOptionsAction: sqlOptions => + { sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); @@ -257,17 +273,23 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration) { - services.AddSwaggerGen(options => { - options.SwaggerDoc("v1", new OpenApiInfo { + public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration) + { + services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new OpenApiInfo + { Title = "eShopOnContainers - Ordering HTTP API", Version = "v1", Description = "The Ordering Service HTTP API" }); - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + { Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() { - Implicit = new OpenApiOAuthFlow() { + Flows = new OpenApiOAuthFlows() + { + Implicit = new OpenApiOAuthFlow() + { AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), Scopes = new Dictionary() @@ -277,14 +299,13 @@ static class CustomExtensionsMethods { } } }); - options.OperationFilter(); }); - return services; } - public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) { + public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) + { services.AddSingleton(); services.AddTransient(); services.AddTransient>( @@ -292,8 +313,10 @@ static class CustomExtensionsMethods { services.AddTransient(); - if (configuration.GetValue("AzureServiceBusEnabled")) { - services.AddSingleton(sp => { + if (configuration.GetValue("AzureServiceBusEnabled")) + { + services.AddSingleton(sp => + { var serviceBusConnectionString = configuration["EventBusConnection"]; var subscriptionClientName = configuration["SubscriptionClientName"]; @@ -301,26 +324,32 @@ static class CustomExtensionsMethods { return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); }); } - else { - services.AddSingleton(sp => { + else + { + services.AddSingleton(sp => + { var logger = sp.GetRequiredService>(); - var factory = new ConnectionFactory() { + var factory = new ConnectionFactory() + { HostName = configuration["EventBusConnection"], DispatchConsumersAsync = true }; - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) { + if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) + { factory.UserName = configuration["EventBusUserName"]; } - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) { + if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) + { factory.Password = configuration["EventBusPassword"]; } var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) { + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + { retryCount = int.Parse(configuration["EventBusRetryCount"]); } @@ -331,18 +360,23 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) { + public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) + { services.AddOptions(); services.Configure(configuration); - services.Configure(options => { - options.InvalidModelStateResponseFactory = context => { - var problemDetails = new ValidationProblemDetails(context.ModelState) { + services.Configure(options => + { + options.InvalidModelStateResponseFactory = context => + { + var problemDetails = new ValidationProblemDetails(context.ModelState) + { Instance = context.HttpContext.Request.Path, Status = StatusCodes.Status400BadRequest, Detail = "Please refer to the errors property for additional details." }; - return new BadRequestObjectResult(problemDetails) { + return new BadRequestObjectResult(problemDetails) + { ContentTypes = { "application/problem+json", "application/problem+xml" } }; }; @@ -351,9 +385,12 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) { - if (configuration.GetValue("AzureServiceBusEnabled")) { - services.AddSingleton(sp => { + public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + { + if (configuration.GetValue("AzureServiceBusEnabled")) + { + services.AddSingleton(sp => + { var serviceBusPersisterConnection = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); var eventBusSubcriptionsManager = sp.GetRequiredService(); @@ -363,15 +400,18 @@ static class CustomExtensionsMethods { eventBusSubcriptionsManager, sp, subscriptionName); }); } - else { - services.AddSingleton(sp => { + else + { + services.AddSingleton(sp => + { var subscriptionClientName = configuration["SubscriptionClientName"]; var rabbitMQPersistentConnection = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); var eventBusSubcriptionsManager = sp.GetRequiredService(); var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) { + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + { retryCount = int.Parse(configuration["EventBusRetryCount"]); } @@ -384,13 +424,15 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) { + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + { // prevent from mapping "sub" claim to nameidentifier. JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); var identityUrl = configuration.GetValue("IdentityUrl"); - services.AddAuthentication("Bearer").AddJwtBearer(options => { + services.AddAuthentication("Bearer").AddJwtBearer(options => + { options.Authority = identityUrl; options.RequireHttpsMetadata = false; options.Audience = "orders"; @@ -399,13 +441,16 @@ static class CustomExtensionsMethods { return services; } - public static IServiceCollection AddCustomAuthorization(this IServiceCollection services, IConfiguration configuration) { - services.AddAuthorization(options => { - options.AddPolicy("ApiScope", policy => { + public static IServiceCollection AddCustomAuthorization(this IServiceCollection services, IConfiguration configuration) + { + services.AddAuthorization(options => + { + options.AddPolicy("ApiScope", policy => + { policy.RequireAuthenticatedUser(); policy.RequireClaim("scope", "orders"); }); }); return services; } -} \ No newline at end of file +}