コード例 #1
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }

            app.UseExceptionHandler(errorApp =>
            {
                errorApp.Run(context =>
                {
                    string InstanceId() => $"urn:backoffice:log:{Guid.NewGuid()}";

                    var errorFeature = context.Features.Get <IExceptionHandlerFeature>();
                    var exception    = errorFeature.Error;

                    if (exception is ValidationException validationException)
                    {
                        var problemDetails = new CustomValidationProblemDetails <ValidationError>
                        {
                            Status   = StatusCodes.Status422UnprocessableEntity,
                            Instance = InstanceId(),
                            Details  = validationException.Failures.Select(e => new ValidationError
                            {
                                Field = e.Key, Errors = e.Value
                            }).ToList()
                        };

                        context.Response.StatusCode = problemDetails.Status.GetValueOrDefault();
                        context.Response.WriteJson(problemDetails, "application/problem+json");
                    }
                    else if (exception is BusinessException backOfficeException)
                    {
                        var problemDetails = new CustomValidationProblemDetails <string>
                        {
                            Status   = StatusCodes.Status422UnprocessableEntity,
                            Details  = new [] { backOfficeException.Message },
                            Instance = InstanceId()
                        };

                        context.Response.StatusCode = problemDetails.Status.GetValueOrDefault();
                        context.Response.WriteJson(problemDetails, "application/problem+json");
                    }
                    else if (exception is NotFoundException)
                    {
                        var problemDetails = new CustomValidationProblemDetails <string>
                        {
                            Status   = StatusCodes.Status404NotFound,
                            Instance = InstanceId()
                        };

                        context.Response.StatusCode = problemDetails.Status.GetValueOrDefault();
                        context.Response.WriteJson(problemDetails, "application/problem+json");
                    }
                    else
                    {
                        var errorDetail = Environment.IsDevelopment()
                            ? exception.Demystify().ToString()
                            : "The instance value should be used to identify the problem when calling customer support";

                        var problemDetails = new ProblemDetails
                        {
                            Title    = "An unexpected error occurred!",
                            Status   = StatusCodes.Status500InternalServerError,
                            Detail   = errorDetail,
                            Instance = InstanceId()
                        };

                        context.Response.StatusCode = problemDetails.Status.GetValueOrDefault();
                        context.Response.WriteJson(problemDetails, "application/problem+json");
                    }

                    // log the exception etc..

                    return(Task.CompletedTask);
                });
            });

            app.UseMiniProfiler();

            app.UseRequestLocalization(options =>
            {
                var supportedCultures = new List <CultureInfo>
                {
                    new CultureInfo("pt-BR"),
                    new CultureInfo("en-US")
                };

                options.DefaultRequestCulture = new RequestCulture("pt-BR");
                // Formatting numbers, dates, etc.
                options.SupportedCultures = supportedCultures;
                // UI strings that we have localized.
                options.SupportedUICultures = supportedCultures;
            });

            app.UseMvc();
            app.UseOpenSpecificationApi();
        }
コード例 #2
0
ファイル: Startup.cs プロジェクト: Savaed/sdc-web-app
        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            // Disable JWT inbound claim name mapping. This behaviour by default maps JWT claim names to their much longer counterparts.
            // See https://mderriey.com/2019/06/23/where-are-my-jwt-claims/
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            // Add validation of antiforgery tokens for unsave methods.
            // See https://docs.microsoft.com/pl-pl/dotnet/api/microsoft.aspnetcore.mvc.autovalidateantiforgerytokenattribute?view=aspnetcore-2.2
            services.AddMvc(options =>
            {
                //options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddFluentValidation()
            .ConfigureApiBehaviorOptions(config =>
            {
                config.InvalidModelStateResponseFactory = context =>
                {
                    // Add custom validation error response.
                    var validationError = new CustomValidationProblemDetails(context);
                    return(new ObjectResult(validationError));
                };
            })
            .AddJsonOptions(options =>
            {
                // Ignore reference loops in JSON responses.
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

                // Convert each enum to its string representation.
                options.SerializerSettings.Converters.Add(new StringEnumConverter());

                // Set DateTime format in JSON, eg. "2019-12-12T23:12:56Z"
                options.SerializerSettings.DateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";
            });

            // In production, the Angular files will be served from this directory.
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });

            // Add default CORS policy.
            services.AddCors(config =>
            {
                config.AddPolicy(ApiConstants.DefaultCorsPolicy, policy =>
                {
                    policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials().Build();
                });
            });

            // Set DbContext for app.
            services.AddDbContext <ApplicationDbContext>(options => options.UseSqlServer(GetConnectionString(ApiConstants.DefaultConnectionString)));

            // Automatically perform database migration.
            //services.BuildServiceProvider().GetService<ApplicationDbContext>().Database.Migrate();

            // Set user requirements.
            services.AddIdentity <IdentityUser, IdentityRole>(config =>
            {
                config.Password.RequireDigit           = true;
                config.Password.RequiredLength         = 8;
                config.Password.RequireLowercase       = true;
                config.Password.RequireNonAlphanumeric = true;
                config.Password.RequireUppercase       = true;

                config.Lockout.AllowedForNewUsers      = true;
                config.Lockout.MaxFailedAccessAttempts = 3;

                config.User.RequireUniqueEmail        = true;
                config.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz";

                config.SignIn.RequireConfirmedEmail = false;
            }).AddEntityFrameworkStores <ApplicationDbContext>();

            // Get JWT settings.
            var jwtSettings = GetJwtSettings(services);

            // Add JWT Bearer authentication.
            services.AddAuthentication(config =>
            {
                config.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
                config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                config.DefaultSignInScheme       = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(config =>
            {
                config.TokenValidationParameters = jwtSettings.GetValidationParameters();
                config.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        // Set the 'Token-Expired: true' header for each request that has provided an expired access token.
                        if (context.Exception is SecurityTokenExpiredException)
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        return(Task.CompletedTask);
                    }
                };
            });

            // Add authorization policies.
            services.AddAuthorization(options =>
            {
                options.AddPolicy(ApiConstants.ApiAdminPolicy, config => config.RequireAuthenticatedUser().RequireClaim(ApiConstants.RoleClaim, ApiConstants.AdministratorRole));
                options.AddPolicy(ApiConstants.ApiUserPolicy, config => config.RequireAuthenticatedUser().RequireClaim(ApiConstants.RoleClaim, ApiConstants.AdministratorRole, ApiConstants.ModeratorRole));
            });

            // Add AutoMapper.
            services.AddAutoMapper(Assembly.GetExecutingAssembly().GetTypes());

            // Replacement of built-in service container with Autofac.
            var containerBuilder = new ContainerBuilder();

            containerBuilder.RegisterModule <ApplicationModule>();
            containerBuilder.Populate(services);
            var container = containerBuilder.Build();

            return(new AutofacServiceProvider(container));
        }