Пример #1
0
        private void DetermineScopeStateMessage()
        {
            const string ScopeMarker         = "Scope: ";
            var          defaultScopeMessage = "Scope " + (this.depth + 1);

            if (this.state == null)
            {
                this.scopeMessage = defaultScopeMessage;
            }
            else if (this.state is string state)
            {
                if (string.IsNullOrWhiteSpace(state))
                {
                    this.scopeMessage = defaultScopeMessage;
                }
                else
                {
                    this.scopeMessage = ScopeMarker + state;
                }
            }
            else if (this.state.GetType().IsValueType)
            {
                this.scopeMessage = ScopeMarker + this.state;
            }
            else
            {
                // The data is probably a complex object or a structured log entry
                this.structuredStateData = JsonConvert.SerializeObject(this.state, DefaultJsonSerializerSettings.Create());
                this.scopeMessage        = defaultScopeMessage;
            }
        }
Пример #2
0
        public CommandRequestStore(IFileStorage storage)
        {
            EnsureArg.IsNotNull(storage, nameof(storage));

            this.storage    = storage;
            this.serializer = new JsonNetSerializer(DefaultJsonSerializerSettings.Create());
        }
Пример #3
0
 public FileStoragePersistCommandBehavior(
     IFileStorage storage   = null,
     ISerializer serializer = null,
     string pathTemplate    = "{id}-{type}.json")
 {
     //EnsureArg.IsNotNull(storage, nameof(storage));
     this.storage = storage ??= new FolderFileStorage(o => o
                                                      .Folder(Path.Combine(Path.GetTempPath(), "naos_commands", "journal")));
     this.serializer   = serializer ?? new JsonNetSerializer(DefaultJsonSerializerSettings.Create());
     this.pathTemplate = pathTemplate ?? "{id}-{type}";
 }
Пример #4
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment environment)
        {
            if (environment.IsProduction())
            {
                app.UseHsts();
            }

            app
            .UseHttpsRedirection()
            .UseNaos(s => s
                     .UseRequestCorrelation()
                     .UseServiceContext()
                     .UseServicePoweredBy()
                     .UseOperations()
                     .UseRequestFiltering()
                     .UseServiceExceptions()
                     .UseServiceDiscoveryRouter())
            .UseSwagger()
            .UseSwaggerUi3();

            // https://blog.elmah.io/asp-net-core-2-2-health-checks-explained/
            // https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.UI/ServiceCollectionExtensions.cs
            app.UseHealthChecks("/health", new HealthCheckOptions // TODO: move to UseNaosOperationsHealthChecks
            {
                ResponseWriter = async(c, r) =>
                {
                    c.Response.ContentType = ContentType.JSON.ToValue();
                    await c.Response.WriteAsync(JsonConvert.SerializeObject(new
                    {
                        status = r.Status.ToString(),
                        took   = r.TotalDuration.ToString(),
                        checks = r.Entries.Select(e => new
                        {
                            //service = c.GetServiceName(),
                            key     = e.Key,
                            status  = e.Value.Status.ToString(),
                            took    = e.Value.Duration.ToString(),
                            message = e.Value.Exception?.Message,
                            data    = e.Value.Data
                        })
                    }, DefaultJsonSerializerSettings.Create()));
                }
            });

            //app.UseHealthChecksUI(s =>
            //{
            //    s.ApiPath = "/health/api";
            //    s.UIPath = "/health/ui";
            //});

            app.UseAuthentication();
            app.UseMvc();
        }
        public static MvcJsonOptions AddDefaultJsonSerializerSettings(this MvcJsonOptions source, JsonSerializerSettings settings = null)
        {
            settings = settings ?? DefaultJsonSerializerSettings.Create();

            // copy some json serializer settings for the mvcoptions
            source.SerializerSettings.ContractResolver     = settings.ContractResolver;
            source.SerializerSettings.Converters           = settings.Converters;
            source.SerializerSettings.DefaultValueHandling = settings.DefaultValueHandling;
            source.SerializerSettings.NullValueHandling    = settings.NullValueHandling;

            return(source);
        }
Пример #6
0
        public static void WriteJson <T>(this HttpResponse response, T content, JsonSerializerSettings settings = null, ContentType contentType = ContentType.JSON)
        {
            response.ContentType = contentType.ToValue();
            using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8))
            {
                using (var jsonWriter = new JsonTextWriter(writer))
                {
                    jsonWriter.CloseOutput         = false;
                    jsonWriter.AutoCompleteOnClose = false;

                    JsonSerializer.Create(settings ?? DefaultJsonSerializerSettings.Create()).Serialize(jsonWriter, content);
                }
            }
        }
Пример #7
0
        public static void WriteJson <T>(this HttpResponse response, T content, ContentType contentType = ContentType.JSON, JsonSerializerSettings settings = null)
        {
            response.ContentType = contentType.ToValue();

#if NETCOREAPP3_1
            var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8);
            using (var jsonWriter = new JsonTextWriter(writer))
            {
                jsonWriter.CloseOutput         = false;
                jsonWriter.AutoCompleteOnClose = false;

                if (settings == null)
                {
                    DefaultSerializer.Serialize(jsonWriter, content);
                }
                else
                {
                    JsonSerializer.Create(DefaultJsonSerializerSettings.Create()).Serialize(jsonWriter, content);
                }
            }

#pragma warning disable CA2012     // Use ValueTasks correctly
            writer.DisposeAsync(); // mitigates 'Synchronous operations are disallowed' issue (netcore3) https://github.com/aspnet/Announcements/issues/342
#pragma warning restore CA2012     // Use ValueTasks correctly
#endif

#if NETSTANDARD2_0
            using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8))
            {
                using (var jsonWriter = new JsonTextWriter(writer))
                {
                    jsonWriter.CloseOutput         = false;
                    jsonWriter.AutoCompleteOnClose = false;

                    if (settings == null)
                    {
                        DefaultSerializer.Serialize(jsonWriter, content);
                    }
                    else
                    {
                        JsonSerializer.Create(DefaultJsonSerializerSettings.Create()).Serialize(jsonWriter, content);
                    }
                }
            }
#endif
        }
Пример #8
0
        public static NaosServicesContextOptions AddSwaggerDocumentation(
            this NaosServicesContextOptions naosOptions)
        {
            EnsureArg.IsNotNull(naosOptions, nameof(naosOptions));

            naosOptions.Context.Services
            .AddSwaggerDocument((c, sp) =>     // TODO: replace with .AddOpenApiDocument, but currently has issues with example model generation in UI
            {
                // TODO: AddNaos.AddSwaggerDocument() ^^^^
                c.SerializerSettings = DefaultJsonSerializerSettings.Create();
                // find all processors which are registerd by various naos features (Command RequestDispatcher/ControllerRegistrations)
                foreach (var documentProcessor in sp.GetServices <IDocumentProcessor>())
                {
                    c.DocumentProcessors.Add(documentProcessor);
                }

                foreach (var operationProcessor in sp.GetServices <IOperationProcessor>())
                {
                    c.OperationProcessors.Add(operationProcessor);
                }

                //c.DocumentProcessors.Add(
                //    new SecurityDefinitionAppender("Bearer", new OpenApiSecurityScheme
                //    {
                //        Name = "Authorization",
                //        Description = "Authorization header using the ApiKey scheme. Example: \"Authorization: ApiKey {value}\"",
                //        In = NSwag.OpenApiSecurityApiKeyLocation.Header,
                //        Type = NSwag.OpenApiSecuritySchemeType.ApiKey // Oauth2/OIDC?
                //    }));

                c.OperationProcessors.Add(new ApiVersionProcessor());
                c.PostProcess = document =>
                {
                    var descriptor               = sp.GetService <Foundation.ServiceDescriptor>();
                    document.Info.Version        = descriptor?.Version.EmptyToNull() ?? "v1";
                    document.Info.Title          = descriptor?.Name.EmptyToNull() ?? "Naos";
                    document.Info.Description    = descriptor?.Tags.ToString(", ").EmptyToNull() ?? "Naos";
                    document.Info.TermsOfService = "None";
                    document.Info.Contact        = new NSwag.OpenApiContact
                    {
                        Name  = "Naos",
                        Email = string.Empty,
                        Url   = "https://github.com/vip32/Naos"
                    };
                };

                if (true)     // if option.includeSecurityHeader
                {
                    var provider = sp.GetService <IAuthenticationSchemeProvider>();
                    if (provider?.GetDefaultChallengeSchemeAsync().Result?.Name == AuthenticationKeys.OidcScheme)
                    {
                        c.AddSecurity("Oauth2", new NSwag.OpenApiSecurityScheme
                        {
                            AuthorizationUrl = "https://global-keycloak.azurewebsites.net/auth/realms/master/protocol/openid-connect/auth",
                            Description      = "Authorization header using the Oauth2 Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                            Name             = "Authorization",
                            Flow             = NSwag.OpenApiOAuth2Flow.Implicit,
                            In   = NSwag.OpenApiSecurityApiKeyLocation.Header,
                            Type = NSwag.OpenApiSecuritySchemeType.OAuth2
                        });
                        c.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("Oauth2"));

                        c.AddSecurity("Oidc", new NSwag.OpenApiSecurityScheme
                        {
                            Scheme           = "Bearer",
                            OpenIdConnectUrl = "https://global-keycloak.azurewebsites.net/auth/realms/master/.well-known/openid-configuration",
                            //AuthorizationUrl = "https://global-keycloak.azurewebsites.net/auth/realms/master/protocol/openid-connect/auth",
                            Description = "Authorization header using the Oidc Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                            Name        = "Authorization",
                            Flow        = NSwag.OpenApiOAuth2Flow.Implicit,
                            In          = NSwag.OpenApiSecurityApiKeyLocation.Header,
                            Type        = NSwag.OpenApiSecuritySchemeType.OpenIdConnect // Oauth2/OIDC?,
                        });
                        c.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("Oidc"));

                        //c.AddSecurity("JWT", new NSwag.OpenApiSecurityScheme
                        //{
                        //    //Schema="Bearer" << has to be added manually in the Auth text box (swaggerui) https://github.com/RicoSuter/NSwag/issues/869
                        //    Description = "Authorization header using a JWT token. Example: \"Authorization: Bearer {jwt}\"",
                        //    Name = "Authorization",
                        //    In = NSwag.OpenApiSecurityApiKeyLocation.Header,
                        //    Type = NSwag.OpenApiSecuritySchemeType.ApiKey
                        //});
                        //c.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT"));
                    }
                    else if (provider?.GetDefaultChallengeSchemeAsync().Result?.Name == AuthenticationKeys.ApiKeyScheme)
                    {
                        c.AddSecurity(AuthenticationKeys.ApiKeyScheme, new NSwag.OpenApiSecurityScheme
                        {
                            Description = "Authorization header using the ApiKey scheme. Example: \"Authorization: ApiKey {key}\"",
                            Name        = "ApiKey",
                            In          = NSwag.OpenApiSecurityApiKeyLocation.Header, // TODO: also allow the auth header to be sent in the querystring
                            Type        = NSwag.OpenApiSecuritySchemeType.ApiKey
                        });
                        c.OperationProcessors.Add(new OperationSecurityScopeProcessor(AuthenticationKeys.ApiKeyScheme));
                    }
                    else if (provider?.GetDefaultChallengeSchemeAsync().Result?.Name == AuthenticationKeys.BasicScheme)
                    {
                        c.AddSecurity(AuthenticationKeys.BasicScheme, new NSwag.OpenApiSecurityScheme
                        {
                            Scheme      = "Basic",
                            Description = "Authorization header using the Basic scheme. Example: \"Basic: {credentials}\"",
                            Name        = "Authorization",
                            In          = NSwag.OpenApiSecurityApiKeyLocation.Header, // TODO: also allow the auth header to be sent in the url https://en.wikipedia.org/wiki/Basic_access_authentication
                            Type        = NSwag.OpenApiSecuritySchemeType.Basic
                        });
                        c.OperationProcessors.Add(new OperationSecurityScopeProcessor(AuthenticationKeys.BasicScheme));
                    }
                }
            });

            naosOptions.Context.Messages.Add("naos services builder: swagger documentation added");
            //naosOptions.Context.Services.AddSingleton(new NaosFeatureInformation { Name = "Swagger", Description = "Documentation", EchoRoute = "naos/swagger/echo" });

            return(naosOptions);
        }
Пример #9
0
        public static NaosServicesContextOptions AddWebApi(
            this NaosServicesContextOptions naosOptions,
            Action <NaosMvcOptions> optionsAction = null,
            Action <IMvcCoreBuilder> optionsMvc   = null)
        {
            var options = new NaosMvcOptions();

            optionsAction?.Invoke(options);

            naosOptions.Context.Services.AddHttpContextAccessor();
            //mvcBuilder.Services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); // needed for GetUrlHelper (IUrlHelperFactory below)
            //mvcBuilder.Services.AddScoped(sp =>
            //{
            //    // enables usage of IUrlHelper https://benfoster.io/blog/injecting-urlhelper-in-aspnet-core-mvc
            //    var actionContext = sp.GetRequiredService<IActionContextAccessor>()?.ActionContext;
            //    if (actionContext == null)
            //    {
            //        throw new ArgumentException("UrlHelper needs an ActionContext, which is usually available in MVC components (Controller/PageModel/ViewComponent)");
            //    }

            //    var factory = sp.GetRequiredService<IUrlHelperFactory>();
            //    return factory?.GetUrlHelper(actionContext);
            //});

            var mvcBuilder = naosOptions.Context.Services
                             //.AddLogging()
                             .AddMvcCore();

            //jsonSerializer ??= JsonSerializer.Create(DefaultJsonSerializerSettings.Create());

            // add the generic repository controllers for all registrations (AddEndpoint)
            if (!options.ControllerRegistrations.IsNullOrEmpty())
            {
                mvcBuilder
                .AddMvcOptions(o =>
                {
                    //o.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build())); // https://tahirnaushad.com/2017/08/28/asp-net-core-2-0-mvc-filters/ or use controller attribute (Authorize)
                    o.Filters.Add <OperationCancelledExceptionFilterAttribute>();
                    o.Conventions.Add(new GeneratedControllerRouteConvention());
                })
                .ConfigureApplicationPartManager(o => o
                                                 .FeatureProviders.Add(
                                                     new GenericRepositoryControllerFeatureProvider(
                                                         options.ControllerRegistrations)));

                mvcBuilder.Services.AddSingleton <IOperationProcessor>(new GenericRepositoryControllerOperationProcessor()); // needed for swagger generation (for each controller registration)
            }
            else
            {
                mvcBuilder.AddMvcOptions(o => { });
                //.AddDataAnnotations()
                //.AddApiExplorer()
                //.AddAuthorization();
            }

            optionsMvc?.Invoke(mvcBuilder);

            //mvcBuilder.AddJsonOptions(o => o.AddDefaultJsonSerializerSettings(options.JsonSerializerSettings));
            mvcBuilder.AddControllersAsServices(); // needed to resolve controllers through di https://andrewlock.net/controller-activation-and-dependency-injection-in-asp-net-core-mvc/
#if NETCOREAPP3_1
            var serializerSettings = DefaultJsonSerializerSettings.Create();
            naosOptions.Context.Services.AddControllers().AddNewtonsoftJson(x => SetSerializerSettings(x, serializerSettings));
            naosOptions.Context.Services.AddControllersWithViews().AddNewtonsoftJson(x => SetSerializerSettings(x, serializerSettings));
            naosOptions.Context.Services.AddRazorPages().AddNewtonsoftJson(x => SetSerializerSettings(x, serializerSettings));
#endif

            return(naosOptions);
        }