コード例 #1
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            services.AddIdentityServer()
            .AddSigningCredential(InMemoryConfiguration.GetX509Certificate2())
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources)
            .AddInMemoryApiResources(InMemoryConfiguration.GetApiResources)
            .AddInMemoryClients(InMemoryConfiguration.GetApiClients)
            .AddTestUsers(InMemoryConfiguration.GetApiUsers);


            services.AddCors(o => o.AddPolicy("CorsPolicy", b =>
            {
                b.WithOrigins(Environment.GetEnvironmentVariable("CLIENT_URL").Split(","))
                .AllowAnyMethod()
                .AllowAnyHeader();
            }));
            services.AddMvcCore(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);
        }
コード例 #2
0
        public void GivenDehydratedBugsResponse_WhenAskingToCreate_ThenItShouldReturnDehydratedObject()
        {
            // arrange
            const string   bugsJson        = "{}";
            IConfiguration configuration   = new InMemoryConfiguration().Instance();
            IHttpService   vstsHttpService = new VstsHttpService(new Uri(configuration["VstsApi:BaseUrl"]), new FakeHttpMessageHandler(bugsJson, new Uri(new Uri(configuration["VstsApi:BaseUrl"]), "/Strickland/_apis/wit/wiql?$top=10000&api-version=5.0-preview.2"), configuration["VstsApi:PAT"]));

            new Privateer().SetStaticField <VstsHttpService, HttpClient>((VstsHttpService)vstsHttpService, "_httpClient", null);
            IBugsFactory bugsFactory = new BugsFactory(vstsHttpService, configuration);

            // act
            Bugs bugs = bugsFactory.Create("Strickland").Result;

            // assert
            JObject jObject = JObject.Parse(JsonConvert.SerializeObject(bugs));

            JToken jBugs = jObject["bugs"];

            jBugs.Should().HaveCount(0);
        }
コード例 #3
0
        public void MigrateInMemoryDataToSqlServer(IApplicationBuilder app)
        {
            using (var scope = app.ApplicationServices.GetService <IServiceScopeFactory>().CreateScope())
            {
                scope.ServiceProvider.GetRequiredService <PersistedGrantDbContext>().Database.Migrate();

                var context = scope.ServiceProvider.GetRequiredService <ConfigurationDbContext>();

                context.Database.Migrate();

                if (!context.Clients.Any())
                {
                    foreach (var client in InMemoryConfiguration.Clients())
                    {
                        context.Clients.Add(client.ToEntity());
                    }

                    context.SaveChanges();
                }

                if (!context.IdentityResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.IdentityResources())
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }

                    context.SaveChanges();
                }

                if (!context.ApiResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.ApiResources())
                    {
                        context.ApiResources.Add(resource.ToEntity());
                    }

                    context.SaveChanges();
                }
            }
        }
コード例 #4
0
ファイル: Startup.cs プロジェクト: philwang1990/Src
        public void ConfigureServices(IServiceCollection services)
        {
            //my user repository
            services.AddScoped <IUserRepository, UserRepository>();

            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            // .AddSigningCredential(new X509Certificate2(@"/etc/nginx/ssl/socialnetwork.pfx", "2wsx3edc"))
            //.AddSigningCredential(new X509Certificate2(@"/Users/jiangzhimin/socialnetwork.pfx", "2wsx3edc"))
            //   .AddSigningCredential(new X509Certificate2(LocaPath + "/Pfx/socialnetwork.pfx", "2wsx3edc"))
            // .AddTestUsers(InMemoryConfiguration.Users().ToList())
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryClients(InMemoryConfiguration.Clients())
            .AddInMemoryApiResources(InMemoryConfiguration.ApiResources())
            .AddProfileService <ProfileService>();


            //Inject the classes we just created
            services.AddTransient <IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();
            services.AddTransient <IProfileService, ProfileService>();//再做一次 像new
        }
コード例 #5
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(new GetTableData(Environment.ContentRootPath));
            services.AddSingleton(new Appsettings(Environment.ContentRootPath));


            services.AddSingleton <IUserService, UserService>();
            services.AddSingleton <IRoleService, RoleService>();
            services.AddSingleton <IUserRoleService, UserRoleService>();

            #region ²âÊÔIdentityServer4
            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents       = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents     = true;
                options.Events.RaiseSuccessEvents     = true;
            })
                          // in-memory, code config
                          .AddTestUsers(InMemoryConfiguration.Users().ToList())
                          .AddInMemoryApiResources(InMemoryConfiguration.GetApiResources())
                          .AddInMemoryClients(InMemoryConfiguration.GetClients())
                          .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources());
            //.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
            //.AddProfileService<CustomProfileService>();


            builder.AddDeveloperSigningCredential();

            if (Environment.IsDevelopment())
            {
                builder.AddDeveloperSigningCredential();
            }
            else
            {
                throw new Exception("need to configure key material");
            }
            #endregion
            services.AddRazorPages();
        }
コード例 #6
0
        private void InitializeDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.GetService <IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetRequiredService <PersistedGrantCustomDbContext>().Database.Migrate();

                var context      = serviceScope.ServiceProvider.GetRequiredService <ConfigurationCustomDbContext>();
                var appDbContext = serviceScope.ServiceProvider.GetRequiredService <ApplicationDbContext>();

                context.Database.Migrate();
                appDbContext.Database.Migrate();

                if (!context.Clients.Any())
                {
                    foreach (var client in InMemoryConfiguration.Clients())
                    {
                        context.Clients.Add(client.ToEntity());
                    }
                    context.SaveChanges();
                }

                if (!context.IdentityResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.GetIdentityResources())
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }

                if (!context.ApiResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.ApiResources())
                    {
                        context.ApiResources.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }
            }
        }
コード例 #7
0
        public void GivenDehydratedProjectsResponse_WhenAskingToCreate_ShouldReturnDehydratedObject()
        {
            // arrange
            const string   projectsJson    = "{}";
            IConfiguration configuration   = new InMemoryConfiguration().Instance();
            IHttpService   vstsHttpService = new VstsHttpService(new Uri(configuration["VstsApi:BaseUrl"]), new FakeHttpMessageHandler(projectsJson, new Uri(new Uri(configuration["VstsApi:BaseUrl"]), "/_apis/projects?api-version=4.1-preview.1"), configuration["VstsApi:PAT"]));

            new Privateer().SetStaticField <VstsHttpService, HttpClient>((VstsHttpService)vstsHttpService, "_httpClient", null);
            IProjectsFactory projectsFactory = new ProjectsFactory(vstsHttpService, configuration);

            // act
            Projects projects = projectsFactory.Create();

            // assert
            JObject jObject = JObject.Parse(JsonConvert.SerializeObject(projects));

            jObject.Value <int>("count").Should().Be(0);

            JToken jProjects = jObject["projects"];

            jProjects.Should().HaveCount(0);
        }
コード例 #8
0
        /// <summary>
        /// InitializeIdentityServerDatabase
        /// </summary>
        /// <param name="app">IApplicationBuilder</param>
        /// <returns></returns>
        private async Task InitializeDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.GetService <IServiceScopeFactory>().CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService <IConfigurationDbContext>();
                if (!context.Clients.Any())
                {
                    foreach (var client in InMemoryConfiguration.Clients())
                    {
                        await context.AddClient(client.ToEntity());
                    }
                }
                if (!context.ApiResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.ApiResources())
                    {
                        await context.AddApiResource(resource.ToEntity());
                    }
                }
                if (!context.IdentityResources.Any())
                {
                    foreach (var identity in InMemoryConfiguration.IdentityResources())
                    {
                        await context.AddIdentityResource(identity.ToEntity());
                    }
                }

                var repo = serviceScope.ServiceProvider.GetService <IUserRepository>();
                if (!repo.FindAll().Any())
                {
                    var user = new User
                    {
                        UserName = "******",
                        Password = "******",
                    };
                    repo.Insert(user);
                }
            }
        }
コード例 #9
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
            .AddSigningCredential(new X509Certificate2(@"C:\dev\todoResources.pfx", ""))
            .AddTestUsers(InMemoryConfiguration.Users().ToList())
            .AddInMemoryClients(InMemoryConfiguration.Clients())
            .AddInMemoryApiResources(InMemoryConfiguration.ApiResources());


            services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority            = "http://localhost:5000";
                options.RequireHttpsMetadata = false;
                options.SaveToken            = true;
                options.ApiName   = "todoResources";
                options.ApiSecret = "SKB Kontur";
            });

            services.AddScoped <ToDoService>();
            services.AddMvc();
        }
コード例 #10
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext <ApplicationDbContext>(options =>
                                                         options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity <ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores <ApplicationDbContext>()
            .AddDefaultTokenProviders();

            // Add application services.
            services.AddTransient <IEmailSender, EmailSender>();

            services.AddMvc();

            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(InMemoryConfiguration.IdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.ApiResources())
            .AddInMemoryClients(InMemoryConfiguration.Clients())
            //.AddAspNetIdentity<ApplicationUser>();
            .AddTestUsers(Users.All());
        }
コード例 #11
0
        public void GivenBugData_WhenAskingToCreate_ThenItShouldReturnBugs()
        {
            // arrange
            string         bugsJson        = new TestData().Bugs();
            IConfiguration configuration   = new InMemoryConfiguration().Instance();
            IHttpService   vstsHttpService = new VstsHttpService(new Uri(configuration["VstsApi:BaseUrl"]), new FakeHttpMessageHandler(bugsJson, new Uri(new Uri(configuration["VstsApi:BaseUrl"]), "/Strickland/_apis/wit/wiql?$top=10000&api-version=5.0-preview.2"), configuration["VstsApi:PAT"]));

            new Privateer().SetStaticField <VstsHttpService, HttpClient>((VstsHttpService)vstsHttpService, "_httpClient", null);
            IBugsFactory bugsFactory = new BugsFactory(vstsHttpService, configuration);

            // act
            Bugs bugs = bugsFactory.Create("Strickland").Result;

            // assert
            JObject jObject = JObject.Parse(JsonConvert.SerializeObject(bugs));

            JToken jBugs = jObject["bugs"];

            jBugs.Should().HaveCount(11);

            jBugs[0].Value <int>("id").Should().Be(777);
            jBugs[0].Value <string>("url").Should().Be("https://premeraservices.visualstudio.com/d30fd324-c3ab-4edc-ac5d-ba4514ba5ec4/_apis/wit/workItems/777");
        }
コード例 #12
0
 public async Task <SecretValidationResult> ValidateAsync(IEnumerable <Secret> secrets, ParsedSecret parsedSecret)
 {
     return(await Task.Run(() =>
     {
         var client = InMemoryConfiguration.Clients().FirstOrDefault(s => s.ClientId == parsedSecret.Id);
         if (client != null)
         {
             foreach (var item in client.ClientSecrets)
             {
                 //验证逻辑 自定义
                 if (item.Value == parsedSecret.Credential.ToString())
                 {
                     return new SecretValidationResult {
                         Success = true
                     };
                 }
             }
             // client.ClientSecrets == parsedSecret.Credential;
         }
         return new SecretValidationResult {
             Success = false
         };
     }));
 }
コード例 #13
0
 public void TestInitialize()
 {
     //Setup connection per tests
     database = new DatabaseContext(InMemoryConfiguration.Configure());
     users    = new UserApi(database);
 }
コード例 #14
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region IdentityServer4+FreeSql
            InMemoryConfiguration.Configuration = this.Configuration;
            services.AddSingleton(Fsql);

            services.AddFreeRepository(filter =>
            {
                filter.Apply <ISoftDeleteAduitEntity>("SoftDelete", a => a.IsDeleted == false);
            }, GetType().Assembly, typeof(AuditBaseRepository <>).Assembly);

            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.GetApis())
            .AddInMemoryClients(InMemoryConfiguration.GetClients())
            .AddProfileService <LinCmsProfileService>()
            .AddResourceOwnerValidator <LinCmsResourceOwnerPasswordValidator>();


            #region AddAuthentication\AddIdentityServerAuthentication
            //AddAuthentication()是把验证服务注册到DI, 并配置了Bearer作为默认模式.

            //AddIdentityServerAuthentication()是在DI注册了token验证的处理者.
            //由于是本地运行, 所以就不使用https了, RequireHttpsMetadata = false.如果是生产环境, 一定要使用https.
            //Authority指定Authorization Server的地址.
            //ApiName要和Authorization Server里面配置ApiResource的name一样.
            //和  AddJwtBearer不能同时使用,目前还不理解区别。
            //services
            //    .AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            //    .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
            //    {
            //        options.RequireHttpsMetadata = false; // for dev env
            //        options.Authority = $"{Configuration["Identity:Protocol"]}://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}"; ;
            //        options.ApiName = Configuration["Service:Name"]; // match with configuration in IdentityServer

            //        options.JwtValidationClockSkew = TimeSpan.FromSeconds(60*5);

            //    });
            #endregion

            #region AddJwtBearer
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                //identityserver4 地址 也就是本项目地址
                options.Authority            = $"{Configuration["Identity:Protocol"]}://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}";
                options.RequireHttpsMetadata = false;
                options.Audience             = Configuration["Service:Name"];

                //options.TokenValidationParameters = new TokenValidationParameters()
                //{
                //    ClockSkew = TimeSpan.Zero   //偏移设置为了0s,用于测试过期策略,完全按照access_token的过期时间策略,默认原本为5分钟
                //};


                //使用Authorize设置为需要登录时,返回json格式数据。
                options.Events = new JwtBearerEvents()
                {
                    OnChallenge = context =>
                    {
                        //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦
                        context.HandleResponse();

                        string msg;
                        ErrorCode errorCode;
                        int statusCode = StatusCodes.Status401Unauthorized;

                        if (context.Error == "invalid_token" &&
                            context.ErrorDescription == "The token is expired")
                        {
                            msg        = "令牌过期";
                            errorCode  = ErrorCode.TokenExpired;
                            statusCode = StatusCodes.Status422UnprocessableEntity;
                        }
                        else if (context.Error == "invalid_token" && context.ErrorDescription.IsNullOrEmpty())
                        {
                            msg       = "令牌失效";
                            errorCode = ErrorCode.TokenInvalidation;
                        }

                        else
                        {
                            msg       = "认证失败,请检查请求头或者重新登陆";
                            errorCode = ErrorCode.TokenInvalidation;
                        }


                        context.Response.ContentType = "application/json";
                        context.Response.StatusCode  = statusCode;
                        context.Response.WriteAsync(new ResultDto(errorCode, msg, context.HttpContext).ToString());

                        return(Task.FromResult(0));
                    }
                };
            });
            #endregion

            #endregion

            services.AddAutoMapper(typeof(Startup).Assembly, typeof(PoemProfile).Assembly);

            services.AddCors(option => option.AddPolicy("cors", policy => policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials().AllowAnyOrigin()));

            #region Mvc
            services.AddMvc(options =>
            {
                options.ValueProviderFactories.Add(new SnakeCaseQueryValueProviderFactory()); //设置SnakeCase形式的QueryString参数
                options.Filters.Add <LinCmsExceptionFilter>();
                options.Filters.Add <LogActionFilterAttribute>();                             // 添加请求方法时的日志记录过滤器
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressUseValidationProblemDetailsForInvalidModelStateResponses = true;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);

                    var resultDto = new ResultDto(ErrorCode.ParameterError, problemDetails.Errors, context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            })
            .AddJsonOptions(opt =>
            {
                //opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                //设置时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                    {
                        ProcessDictionaryKeys = true
                    }
                };
            });
            #endregion

            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            #region Scrutor 与单个单个注册等价,不过可批量注册
            //services.AddScoped<ILogService, LogService>();
            //services.AddScoped<IUserSevice, UserService>();
            services.Scan(scan => scan
                          //加载Startup这个类所在的程序集
                          .FromAssemblyOf <Startup>()
                          // 表示要注册那些类,上面的代码还做了过滤,只留下了以 Service 结尾的类
                          .AddClasses(classes => classes.Where(t => t.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase)))
                          //表示将类型注册为提供其所有公共接口作为服务
                          .AsImplementedInterfaces()
                          //表示注册的生命周期为 Transient
                          .WithTransientLifetime()
                          // We start out with all types in the assembly of ITransientService
                          .FromAssemblyOf <IScopeDependency>()
                          // AddClasses starts out with all public, non-abstract types in this assembly.
                          // These types are then filtered by the delegate passed to the method.
                          // In this case, we filter out only the classes that are assignable to ITransientService.
                          .AddClasses(classes => classes.AssignableTo <ITransientDependency>())
                          // We then specify what type we want to register these classes as.
                          // In this case, we want to register the types as all of its implemented interfaces.
                          // So if a type implements 3 interfaces; A, B, C, we'd end up with three separate registrations.
                          .AsImplementedInterfaces()
                          // And lastly, we specify the lifetime of these registrations.
                          .WithTransientLifetime()
                          );
            #endregion

            #region Swagger
            //Swagger重写PascalCase,改成SnakeCase模式
            services.TryAddEnumerable(ServiceDescriptor
                                      .Transient <IApiDescriptionProvider, SnakeCaseQueryParametersApiDescriptionProvider>());

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info()
                {
                    Title = "LinCms", Version = "v1"
                });
                var security = new Dictionary <string, IEnumerable <string> > {
                    { "Bearer", new string[] { } },
                };
                options.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new ApiKeyScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization", //jwt默认的参数名称
                    In          = "header",        //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = "apiKey"
                });

                string basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
                string xmlPath  = Path.Combine(basePath, "LinCms.Web.xml");
                options.IncludeXmlComments(xmlPath);

                options.OperationFilter <SwaggerFileHeaderParameter>();
            });
            #endregion

            //将Handler注册到DI系统中
            services.AddScoped <IAuthorizationHandler, PermissionAuthorizationHandler>();

            services.Configure <FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit   = 1024 * 1024 * 2;
                options.MultipartHeadersCountLimit = 10;
            });
        }
コード例 #15
0
ファイル: InMemoryTests.cs プロジェクト: uvirra/realm-dotnet
        protected override void CustomSetUp()
        {
            base.CustomSetUp();

            _config = new InMemoryConfiguration(Guid.NewGuid().ToString());
        }
コード例 #16
0
        public void Init()
        {
            var config = new InMemoryConfiguration("borkbork");

            realm = Realm.GetInstance(config);
        }
コード例 #17
0
        public void ConfigureServices(IServiceCollection services)
        {
            InMemoryConfiguration.Configuration = this.Configuration;

            services.AddContext();

            services.AddCors();
            services.AddHash();
            services.AddCryptography("lin-cms-dotnetcore-cryptography");

            services.ConfigureApplicationCookie(options =>
            {
                options.LoginPath = "/account/login";
            });
            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(120);
            });

            services.AddIdentityServer(options => new IdentityServerOptions
            {
                UserInteraction = new UserInteractionOptions
                {
                    LoginUrl  = "/account/login",
                    LogoutUrl = "/account/logout",
                }
            })
#if DEBUG
            .AddDeveloperSigningCredential()
#endif
#if !DEBUG
            .AddSigningCredential(new X509Certificate2(
                                      Path.Combine(AppContext.BaseDirectory, Configuration["Certificates:Path"]),
                                      Configuration["Certificates:Password"])
                                  )
#endif
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.GetApis())
            .AddInMemoryClients(InMemoryConfiguration.GetClients())
            .AddInMemoryApiScopes(InMemoryConfiguration.GetApiScopes())
            .AddProfileService <LinCmsProfileService>()
            .AddResourceOwnerValidator <LinCmsResourceOwnerPasswordValidator>();

            #region Swagger

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                string ApiName = "LinCms.IdentityServer4";
                options.SwaggerDoc("v1", new OpenApiInfo()
                {
                    Title   = ApiName + RuntimeInformation.FrameworkDescription,
                    Version = "v1",
                    Contact = new OpenApiContact {
                        Name = ApiName, Email = "*****@*****.**", Url = new Uri("https://www.cnblogs.com/igeekfan/")
                    },
                    License = new OpenApiLicense {
                        Name = ApiName + " 官方文档", Url = new Uri("https://luoyunchong.github.io/vovo-docs/dotnetcore/lin-cms/dotnetcore-start.html")
                    }
                });
                var security = new OpenApiSecurityRequirement()
                {
                    { new OpenApiSecurityScheme
                      {
                          Reference = new OpenApiReference()
                          {
                              Id   = "Bearer",
                              Type = ReferenceType.SecurityScheme
                          }
                      }, Array.Empty <string>() }
                };
                options.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",          //jwt默认的参数名称
                    In          = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = SecuritySchemeType.ApiKey
                });
                try
                {
                    string xmlPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml");
                    options.IncludeXmlComments(xmlPath, true);
                }
                catch (Exception ex)
                {
                    Log.Logger.Warning(ex.Message);
                }
                options.AddServer(new OpenApiServer()
                {
                    Url         = "",
                    Description = "vvv"
                });
                options.CustomOperationIds(apiDesc =>
                {
                    var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
                    return(controllerAction.ControllerName + "-" + controllerAction.ActionName);
                });
            });
            #endregion

            services.AddTransient <IUserRepository, UserRepository>();
            services.AddTransient <IUserIdentityService, UserIdentityService>();
            services.AddTransient <ICurrentUser, CurrentUser>();
            services.AddTransient(typeof(IAuditBaseRepository <>), typeof(AuditBaseRepository <>));
            services.AddTransient(typeof(IAuditBaseRepository <,>), typeof(AuditBaseRepository <,>));
            //services.AddTransient<CustomExceptionMiddleWare>();

            services.AddAutoMapper(typeof(UserProfile).Assembly);

            services.AddControllersWithViews(options =>
            {
                options.Filters.Add <LinCmsExceptionFilter>();
            })
            .AddNewtonsoftJson(opt =>
            {
                //忽略循环引用
                opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                //设置自定义时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                //opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                //{
                //    NamingStrategy = new SnakeCaseNamingStrategy()
                //    {
                //        ProcessDictionaryKeys = true
                //    }
                //};
            })
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressConsumesConstraintForFormFileParameters = true;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);

                    var resultDto = new UnifyResponseDto(ErrorCode.ParameterError, problemDetails.Errors, context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            });
            services.AddHttpsRedirection(options =>
            {
                options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
                options.HttpsPort          = 443;
            });
            services.AddHealthChecks();
        }
コード例 #18
0
 public Lobby(string friendlyName, AuthenticatedUser owner, GameManager gameManager, InMemoryConfiguration inMemoryConfiguration)
 {
     this.LobbyId               = friendlyName;
     this.Owner                 = owner;
     this.GameManager           = gameManager;
     this.InMemoryConfiguration = inMemoryConfiguration;
     InitializeAllGameStates();
 }
コード例 #19
0
        public void MigrateInMemoryDataToSqlServer(IApplicationBuilder app)
        {
            using (var scope = app.ApplicationServices.GetService <IServiceScopeFactory>().CreateScope())
            {
                scope.ServiceProvider.GetRequiredService <PersistedGrantDbContext>().Database.Migrate();
                var context = scope.ServiceProvider.GetRequiredService <ConfigurationDbContext>();
                context.Database.Migrate();

                if (!context.Clients.Any())
                {
                    foreach (var client in InMemoryConfiguration.Clients())
                    {
                        context.Clients.Add(client.ToEntity());
                    }

                    context.SaveChanges();
                }

                if (!context.IdentityResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.IdentityResources())
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }

                    context.SaveChanges();
                }

                if (!context.ApiResources.Any())
                {
                    foreach (var resource in InMemoryConfiguration.ApiResources())
                    {
                        context.ApiResources.Add(resource.ToEntity());
                    }

                    context.SaveChanges();
                }

                if (!context.ApiScopes.Any())
                {
                    foreach (var apiScope in InMemoryConfiguration.ApiScopes())
                    {
                        context.ApiScopes.Add(apiScope.ToEntity());
                    }

                    context.SaveChanges();
                }

                var applicationContext = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                applicationContext.Database.Migrate();

                if (!applicationContext.Users.Any())
                {
                    foreach (var user in InMemoryConfiguration.Users())
                    {
                        var passwordHasher = new PasswordHasher <ApplicationUser>();
                        var appUser        = new ApplicationUser
                        {
                            UserName           = "******",
                            NormalizedUserName = "******",
                            CustomElement      = "custom element"
                        };

                        appUser.PasswordHash = passwordHasher.HashPassword(appUser, "Test123!");
                        applicationContext.Users.Add(appUser);
                    }

                    applicationContext.SaveChanges();
                }
            }
        }
コード例 #20
0
 public void Setup()
 {
     _sut = new InMemoryConfiguration();
 }
コード例 #21
0
 public LobbyController(ILogger <LobbyController> logger, GameManager gameManager, IServiceProvider serviceProvider, InMemoryConfiguration inMemoryConfiguration)
 {
     this.GameManager           = gameManager;
     this.Logger                = logger;
     this.ServiceProvider       = serviceProvider;
     this.InMemoryConfiguration = inMemoryConfiguration;
 }
コード例 #22
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            InMemoryConfiguration.Configuration = this.Configuration;

            services.AddSingleton(Fsql);
            services.AddScoped <IUnitOfWork>(sp => sp.GetService <IFreeSql>().CreateUnitOfWork());

            services.AddFreeRepository(filter =>
            {
                filter.Apply <IDeleteAduitEntity>("IsDeleted", a => a.IsDeleted == false);
            }, GetType().Assembly, typeof(AuditBaseRepository <>).Assembly);

            services.AddIdentityServer()
#if DEBUG
            .AddDeveloperSigningCredential()
#endif
#if DEBUG
            .AddSigningCredential(new X509Certificate2(
                                      Path.Combine(AppContext.BaseDirectory, Configuration["Certificates:Path"]),
                                      Configuration["Certificates:Password"])
                                  )
#endif
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.GetApis())
            .AddInMemoryClients(InMemoryConfiguration.GetClients())
            .AddProfileService <LinCmsProfileService>()
            .AddResourceOwnerValidator <LinCmsResourceOwnerPasswordValidator>();

            #region Swagger
            //Swagger重写PascalCase,改成SnakeCase模式
            services.TryAddEnumerable(ServiceDescriptor
                                      .Transient <IApiDescriptionProvider, SnakeCaseQueryParametersApiDescriptionProvider>());

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo()
                {
                    Title = "LinCms.IdentityServer4", Version = "v1"
                });
                var security = new OpenApiSecurityRequirement()
                {
                    { new OpenApiSecurityScheme
                      {
                          Reference = new OpenApiReference()
                          {
                              Id   = "Bearer",
                              Type = ReferenceType.SecurityScheme
                          }
                      }, Array.Empty <string>() }
                };
                options.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",          //jwt默认的参数名称
                    In          = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = SecuritySchemeType.ApiKey
                });

                string xmlPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml");
                options.IncludeXmlComments(xmlPath);
            });
            #endregion

            services.AddTransient <ICurrentUser, CurrentUser>();

            services.AddControllers();
        }
コード例 #23
0
ファイル: GettersTests.cs プロジェクト: MikhailApsalikov/Selp
 public void GetByFilterShouldUseDefaultIfPageSizeIfItIsIncorrect()
 {
     ISelpConfiguration configuration = new InMemoryConfiguration();
     configuration.DefaultPageSize = 11;
     InitRepositoryParams(true, configuration);
     int total;
     var filter = new BaseFilter
     {
         PageSize = -55
     };
     List<FakeEntity> list = repository.GetByFilter(filter, out total);
     Assert.IsNotNull(list, "Result is null");
     Assert.AreEqual(11, list.Count, "Result count is wrong");
     Assert.AreEqual(11, filter.PageSize, "Filter hasn't been normalized");
     Assert.AreEqual(100, total, "Total is incorrect");
     Assert.AreEqual(11, filter.PageSize, "Returned PageSize incorrect");
 }
コード例 #24
0
ファイル: Startup.cs プロジェクト: ngruson/AdventureWorks
        public void MigrateInMemoryDataToSqlServer(IApplicationBuilder app)
        {
            using var scope = app.ApplicationServices.GetService <IServiceScopeFactory>().CreateScope();
            scope.ServiceProvider.GetRequiredService <PersistedGrantDbContext>().Database.Migrate();

            var context = scope.ServiceProvider.GetRequiredService <ConfigurationDbContext>();

            context.Database.Migrate();

            if (!context.Clients.Any())
            {
                foreach (var client in InMemoryConfiguration.Clients())
                {
                    context.Clients.Add(client.ToEntity());
                }
                context.SaveChanges();
            }

            if (!context.IdentityResources.Any())
            {
                foreach (var resource in InMemoryConfiguration.IdentityResources())
                {
                    context.IdentityResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }

            if (!context.ApiResources.Any())
            {
                foreach (var resource in InMemoryConfiguration.ApiResources())
                {
                    context.ApiResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }

            if (!context.ApiScopes.Any())
            {
                foreach (var apiScope in InMemoryConfiguration.ApiScopes())
                {
                    context.ApiScopes.Add(apiScope.ToEntity());
                }
                context.SaveChanges();
            }

            var userManager = scope.ServiceProvider.GetRequiredService <UserManager <ApplicationUser> >();

            foreach (var user in InMemoryConfiguration.Users())
            {
                var appUser = userManager.FindByNameAsync(user.Username).Result;
                if (appUser == null)
                {
                    appUser = new ApplicationUser
                    {
                        UserName       = user.Username,
                        Email          = user.Claims.Single(c => c.Type == "email").Value,
                        EmailConfirmed = true
                    };
                    var result = userManager.CreateAsync(appUser, user.Password).Result;
                    result = userManager.AddClaimsAsync(appUser, new Claim[] {
                        new Claim(JwtClaimTypes.Name, "Nils Gruson"),
                        new Claim(JwtClaimTypes.GivenName, "Nils"),
                        new Claim(JwtClaimTypes.FamilyName, "Gruson")
                    }).Result;
                }
                ;
            }
        }
コード例 #25
0
        public void ConfigureServices(IServiceCollection services)
        {
            InMemoryConfiguration.Configuration = this.Configuration;

            services.AddContext();

            services.AddIdentityServer()
#if DEBUG
            .AddDeveloperSigningCredential()
#endif
#if !DEBUG
            .AddSigningCredential(new X509Certificate2(
                                      Path.Combine(AppContext.BaseDirectory, Configuration["Certificates:Path"]),
                                      Configuration["Certificates:Password"])
                                  )
#endif
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.GetApis())
            .AddInMemoryClients(InMemoryConfiguration.GetClients())
            .AddProfileService <LinCmsProfileService>()
            .AddResourceOwnerValidator <LinCmsResourceOwnerPasswordValidator>();

            #region Swagger

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo()
                {
                    Title = "LinCms.IdentityServer4", Version = "v1"
                });
                var security = new OpenApiSecurityRequirement()
                {
                    { new OpenApiSecurityScheme
                      {
                          Reference = new OpenApiReference()
                          {
                              Id   = "Bearer",
                              Type = ReferenceType.SecurityScheme
                          }
                      }, Array.Empty <string>() }
                };
                options.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",          //jwt默认的参数名称
                    In          = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = SecuritySchemeType.ApiKey
                });

                string xmlPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml");
                options.IncludeXmlComments(xmlPath);
            });
            #endregion

            services.AddTransient <IUserRepository, UserRepository>();
            services.AddTransient <IUserIdentityService, UserIdentityService>();
            services.AddTransient <ICurrentUser, CurrentUser>();
            services.AddTransient(typeof(IAuditBaseRepository <>), typeof(AuditBaseRepository <>));
            services.AddTransient(typeof(IAuditBaseRepository <,>), typeof(AuditBaseRepository <,>));
            services.AddTransient <CustomExceptionMiddleWare>();

            services.AddCors();
            services.AddAutoMapper(typeof(UserProfile).Assembly);

            services.AddControllers(options =>
            {
                //options.Filters.Add<LinCmsExceptionFilter>();
            })
            .AddNewtonsoftJson(opt =>
            {
                //opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                //设置自定义时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                    {
                        ProcessDictionaryKeys = true
                    }
                };
            })
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressConsumesConstraintForFormFileParameters = true;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);

                    var resultDto = new UnifyResponseDto(ErrorCode.ParameterError, problemDetails.Errors, context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            });
            services.AddHealthChecks();
        }
コード例 #26
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region IdentityServer4+FreeSql
            InMemoryConfiguration.Configuration = this.Configuration;
            services.AddSingleton(Fsql);
            //services.AddScoped(typeof(IUnitOfWork), typeof(UnitOfWork));
            services.AddScoped <IUnitOfWork>(sp => sp.GetService <IFreeSql>().CreateUnitOfWork());

            services.AddFreeRepository(filter =>
            {
                filter.Apply <IDeleteAduitEntity>("IsDeleted", a => a.IsDeleted == false);
            }, GetType().Assembly, typeof(AuditBaseRepository <>).Assembly);

            services.AddIdentityServer()
#if DEBUG
            .AddDeveloperSigningCredential()
#endif
#if !DEBUG
            .AddSigningCredential(new X509Certificate2(Path.Combine(AppContext.BaseDirectory,
                                                                    Configuration["Certificates:Path"]),
                                                       Configuration["Certificates:Password"]))
#endif
            .AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
            .AddInMemoryApiResources(InMemoryConfiguration.GetApis())
            .AddInMemoryClients(InMemoryConfiguration.GetClients())
            .AddProfileService <LinCmsProfileService>()
            .AddResourceOwnerValidator <LinCmsResourceOwnerPasswordValidator>();


            #region AddAuthentication\AddIdentityServerAuthentication
            //AddAuthentication()是把验证服务注册到DI, 并配置了Bearer作为默认模式.

            //AddIdentityServerAuthentication()是在DI注册了token验证的处理者.
            //由于是本地运行, 所以就不使用https了, RequireHttpsMetadata = false.如果是生产环境, 一定要使用https.
            //Authority指定Authorization Server的地址.
            //ApiName要和Authorization Server里面配置ApiResource的name一样.
            //和  AddJwtBearer不能同时使用,目前还不理解区别。
            //services
            //    .AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            //    .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
            //    {
            //        options.RequireHttpsMetadata = false; // for dev env
            //        options.Authority = $"{Configuration["Identity:Protocol"]}://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}"; ;
            //        options.ApiName = Configuration["Service:Name"]; // match with configuration in IdentityServer

            //        //options.JwtValidationClockSkew = TimeSpan.FromSeconds(60 * 5);

            //    });
            #endregion

            #region AddJwtBearer
            services.AddAuthentication(opts =>
            {
                opts.DefaultScheme             = CookieAuthenticationDefaults.AuthenticationScheme;
                opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                //opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.LoginPath  = "/cms/oauth2/signin";
                options.LogoutPath = "/cms/oauth2/signout";
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                //identityserver4 地址 也就是本项目地址
                options.Authority            = $"{Configuration["Identity:Protocol"]}://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}";
                options.RequireHttpsMetadata = false;
                options.Audience             = Configuration["Service:Name"];

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    // The signing key must match!
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(
                        Encoding.ASCII.GetBytes(Configuration["Authentication:JwtBearer:SecurityKey"])),

                    // Validate the JWT Issuer (iss) claim
                    ValidateIssuer = true,
                    ValidIssuer    = Configuration["Authentication:JwtBearer:Issuer"],

                    // Validate the JWT Audience (aud) claim
                    ValidateAudience = true,
                    ValidAudience    = Configuration["Authentication:JwtBearer:Audience"],

                    // Validate the token expiry
                    ValidateLifetime = true,

                    // If you want to allow a certain amount of clock drift, set that here
                    //ClockSkew = TimeSpan.Zero
                };


                //options.TokenValidationParameters = new TokenValidationParameters()
                //{
                //    ClockSkew = TimeSpan.Zero   //偏移设置为了0s,用于测试过期策略,完全按照access_token的过期时间策略,默认原本为5分钟
                //};


                //使用Authorize设置为需要登录时,返回json格式数据。
                options.Events = new JwtBearerEvents()
                {
                    OnAuthenticationFailed = context =>
                    {
                        //Token expired
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        return(Task.CompletedTask);
                    },
                    OnChallenge = context =>
                    {
                        //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦
                        context.HandleResponse();

                        string msg;
                        ErrorCode errorCode;
                        int statusCode = StatusCodes.Status401Unauthorized;

                        if (context.Error == "invalid_token" &&
                            context.ErrorDescription == "The token is expired")
                        {
                            msg        = "令牌过期";
                            errorCode  = ErrorCode.TokenExpired;
                            statusCode = StatusCodes.Status422UnprocessableEntity;
                        }
                        else if (context.Error == "invalid_token" && context.ErrorDescription.IsNullOrEmpty())
                        {
                            msg       = "令牌失效";
                            errorCode = ErrorCode.TokenInvalidation;
                        }

                        else
                        {
                            msg       = "请先登录";//""认证失败,请检查请求头或者重新登录";
                            errorCode = ErrorCode.AuthenticationFailed;
                        }

                        context.Response.ContentType = "application/json";
                        context.Response.StatusCode  = statusCode;
                        context.Response.WriteAsync(new ResultDto(errorCode, msg, context.HttpContext).ToString());

                        return(Task.FromResult(0));
                    }
                };
            })
            .AddGitHub(options =>
            {
                options.ClientId     = Configuration["Authentication:GitHub:ClientId"];
                options.ClientSecret = Configuration["Authentication:GitHub:ClientSecret"];
                options.Scope.Add("user:email");
                //authenticateResult.Principal.FindFirst(ClaimTypes.Uri)?.Value;  得到GitHub头像
                options.ClaimActions.MapJsonKey(LinConsts.Claims.AvatarUrl, "avatar_url");
                options.ClaimActions.MapJsonKey(LinConsts.Claims.BIO, "bio");
                options.ClaimActions.MapJsonKey(LinConsts.Claims.BlogAddress, "blog");
            });
            #endregion

            #endregion

            services.AddAutoMapper(typeof(UserProfile).Assembly, typeof(PoemProfile).Assembly);

            //services.AddCors(option => option.AddPolicy("cors", policy => policy.AllowAnyHeader().AllowAnyMethod().AllowCredentials().AllowAnyOrigin()));
            services.AddCors();

            #region Mvc
            services.AddControllers(options =>
            {
                options.ValueProviderFactories.Add(new SnakeCaseQueryValueProviderFactory()); //设置SnakeCase形式的QueryString参数
                options.Filters.Add <LinCmsExceptionFilter>();
                options.Filters.Add <LogActionFilterAttribute>();                             // 添加请求方法时的日志记录过滤器
            })
            .AddNewtonsoftJson(opt =>
            {
                //opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:MM:ss";
                //设置时间戳格式
                opt.SerializerSettings.Converters = new List <JsonConverter>()
                {
                    new LinCmsTimeConverter()
                };
                // 设置下划线方式,首字母是小写
                opt.SerializerSettings.ContractResolver = new DefaultContractResolver()
                {
                    NamingStrategy = new SnakeCaseNamingStrategy()
                    {
                        ProcessDictionaryKeys = true
                    }
                };
            })
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressConsumesConstraintForFormFileParameters = true; //SuppressUseValidationProblemDetailsForInvalidModelStateResponses;
                //自定义 BadRequest 响应
                options.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState);

                    var resultDto = new ResultDto(ErrorCode.ParameterError, problemDetails.Errors, context.HttpContext);

                    return(new BadRequestObjectResult(resultDto)
                    {
                        ContentTypes = { "application/json" }
                    });
                };
            });
            #endregion

            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();


            #region Scrutor 与单个单个注册等价,不过可批量注册
            //services.AddScoped<ILogService, LogService>();
            //services.AddScoped<IUserSevice, UserService>();
            services.Scan(scan => scan
                          //加载Startup这个类所在的程序集
                          .FromAssemblyOf <IAppService>()
                          // 表示要注册那些类,上面的代码还做了过滤,只留下了以 Service 结尾的类
                          .AddClasses(classes => classes.Where(t => t.Name != "IFileService" && t.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase)))
                          .UsingRegistrationStrategy(RegistrationStrategy.Skip)
                          //表示将类型注册为提供其所有公共接口作为服务
                          .AsImplementedInterfaces()
                          //表示注册的生命周期为 Transient
                          .WithTransientLifetime()
                          // We start out with all types in the assembly of ITransientService
                          .FromAssemblyOf <IScopeDependency>()
                          // AddClasses starts out with all public, non-abstract types in this assembly.
                          // These types are then filtered by the delegate passed to the method.
                          // In this case, we filter out only the classes that are assignable to ITransientService.
                          .AddClasses(classes => classes.AssignableTo <ITransientDependency>())
                          // We then specify what type we want to register these classes as.
                          // In this case, we want to register the types as all of its implemented interfaces.
                          // So if a type implements 3 interfaces; A, B, C, we'd end up with three separate registrations.
                          .AsImplementedInterfaces()
                          // And lastly, we specify the lifetime of these registrations.
                          .WithTransientLifetime()
                          );

            string serviceName = Configuration.GetSection("FILE:SERVICE").Value;

            if (serviceName == LinFile.LocalFileService)
            {
                services.AddTransient <IFileService, LocalFileService>();
            }
            else
            {
                services.AddTransient <IFileService, QiniuService>();
            }
            #endregion

            #region Swagger
            //Swagger重写PascalCase,改成SnakeCase模式
            services.TryAddEnumerable(ServiceDescriptor
                                      .Transient <IApiDescriptionProvider, SnakeCaseQueryParametersApiDescriptionProvider>());

            //Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo()
                {
                    Title = "LinCms", Version = "v1"
                });
                var security = new OpenApiSecurityRequirement()
                {
                    { new OpenApiSecurityScheme
                      {
                          Reference = new OpenApiReference()
                          {
                              Id   = "Bearer",
                              Type = ReferenceType.SecurityScheme
                          }
                      }, Array.Empty <string>() }
                };
                options.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
                    Name        = "Authorization",          //jwt默认的参数名称
                    In          = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中)
                    Type        = SecuritySchemeType.ApiKey
                });

                string xmlPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml");
                options.IncludeXmlComments(xmlPath);
            });
            #endregion

            //将Handler注册到DI系统中
            services.AddScoped <IAuthorizationHandler, PermissionAuthorizationHandler>();

            services.Configure <FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit   = 1024 * 1024 * 2;
                options.MultipartHeadersCountLimit = 10;
            });

            IConfigurationSection configurationSection = Configuration.GetSection("ConnectionStrings:Default");
            services.AddCap(x =>
            {
                x.UseMySql(configurationSection.Value);

                x.UseRabbitMQ("localhost");
                x.UseDashboard();
                x.FailedRetryCount        = 5;
                x.FailedThresholdCallback = (type, msg) =>
                {
                    Console.WriteLine(
                        $@"A message of type {type} failed after executing {x.FailedRetryCount} several times, requiring manual troubleshooting. Message name: {msg.GetName()}");
                };
            });
        }
コード例 #27
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var connectionString   = Configuration.GetConnectionString("DefaultConnection");
            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

            services.AddSingleton <IServiceConfigurationProxy, ServiceConfigurationProxy>();
            services.AddTransient <IVerificationProxy, VerificationProxy>();
            services.AddTransient <IAppletUserService, AppletUserService>();
            services.AddTransient <IPaymentServiceProxy, PaymentServiceProxy>();

            services.Configure <ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
            services.AddOptions();

            services.AddDbContext <ApplicationDbContext>(options =>
                                                         options.UseMySql(connectionString));

            services.AddIdentity <ApplicationUser, IdentityRole>(options =>
            {
                // 配置身份选项
                // 密码配置
                options.Password.RequireDigit           = false; //是否需要数字(0-9).
                options.Password.RequiredLength         = 6;     //设置密码长度最小为6
                options.Password.RequireNonAlphanumeric = false; //是否包含非字母或数字字符。
                options.Password.RequireUppercase       = false; //是否需要大写字母(A-Z).
                options.Password.RequireLowercase       = false; //是否需要小写字母(a-z).

                // 锁定设置
                options.Lockout.DefaultLockoutTimeSpan  = TimeSpan.FromMinutes(30); //账户锁定时长30分钟
                options.Lockout.MaxFailedAccessAttempts = 10;                       //10次失败的尝试将账户锁定

                // 用户设置
                options.User.RequireUniqueEmail = false; //是否Email地址必须唯一
            })
            .AddEntityFrameworkStores <ApplicationDbContext>()
            .AddDefaultTokenProviders();

            // Add application services.
            services.AddTransient <IEmailSender, EmailSender>();


            services.AddIdentityServer()
            .AddSigningCredential(new X509Certificate2(@"./certificate/gooios.pfx", "!QAZ2wsx098", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable))
            .AddTestUsers(InMemoryConfiguration.Users().ToList())
            .AddConfigurationStore <ConfigurationCustomDbContext>(options =>
            {
                options.ConfigureDbContext = builder =>
                                             builder.UseMySql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            })
            .AddOperationalStore <PersistedGrantCustomDbContext>(options =>
            {
                options.ConfigureDbContext = builder =>
                                             builder.UseMySql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));

                options.EnableTokenCleanup   = true;
                options.TokenCleanupInterval = 3600 * 24 * 7;
            })
            .AddAspNetIdentity <ApplicationUser>()
            //.AddResourceOwnerValidator<SessionKeyValidator>()
            .AddResourceOwnerValidator <CookAppSessionKeyValidator>()
            .AddProfileService <ProfileService>();



            services.AddMvc();
        }