public UserController( UserDbContext _db, RedisService _redis, IStringLocalizer <UserController> _localizer, ISmsSender _sms, EmailService _email, UserManager <AppUser> _userManager, TenantDbContext _tenantDbContext, ConfigurationDbContext _configDbContext, IDataProtectionProvider _provider, TenantService _tenantService, IdentityServer4MicroServiceOptions _ismsOptions) { // 多语言 l = _localizer; db = _db; redis = _redis; sms = _sms; email = _email; userManager = _userManager; tenantDbContext = _tenantDbContext; configDbContext = _configDbContext; protector = _provider.CreateProtector(GetType().FullName).ToTimeLimitedDataProtector(); tenantService = _tenantService; ismsOptions = _ismsOptions; }
public MobileCodeGrantValidator(ITokenValidator validator, UserDbContext db, RedisService redis, UserManager <AppUser> userManager, IdentityServer4MicroServiceOptions ismsOptions) { _validator = validator; _db = db; _redis = redis; _userManager = userManager; _ismsOptions = ismsOptions; }
/// <summary> /// Creates a builder. /// </summary> /// <param name="services">The services.</param> /// <param name="ismsOptions">The Options.</param> /// <param name="configuration">The Configuration.</param> /// <returns></returns> public static IISMSServiceBuilder AddIdentityServer4MicroService( this IServiceCollection services, IConfiguration configuration, Action <IdentityServer4MicroServiceOptions> ismsOptions = null) { var Options = new IdentityServer4MicroServiceOptions(); if (ismsOptions != null) { ismsOptions.Invoke(Options); } var builder = new ISMSServiceBuilder(services); builder.Services.AddSingleton(Options); builder.Services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); #region Cors if (Options.EnableCors) { builder.Services.AddCors(options => { options.AddPolicy("cors-allowanonymous", x => { x.AllowAnyHeader(); x.AllowAnyMethod(); x.AllowAnyOrigin(); x.AllowCredentials(); }); }); } #endregion #region WebEncoders if (Options.EnableWebEncoders) { services.AddWebEncoders(opt => { opt.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.All); }); } #endregion #region AuthorizationPolicy if (Options.EnableAuthorizationPolicy) { builder.Services.AddAuthorization(options => { var ISMSTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(x => x.BaseType != null && x.BaseType.Name.Equals("ApiControllerBase")).ToList(); var isms_policies = PolicyConfigs(ISMSTypes); var EntryTypes = Assembly.GetEntryAssembly().GetTypes() .Where(x => x.BaseType != null && (x.BaseType.Name.Equals("ApiControllerBase") || x.BaseType.Name.Equals("ControllerBase"))).ToList(); var entry_policies = PolicyConfigs(EntryTypes); if (entry_policies.Count > 0) { isms_policies.AddRange(entry_policies); } foreach (var policyConfig in isms_policies) { #region Client的权限策略 policyConfig.Scopes.ForEach(x => { var policyName = $"{PolicyKey.ClientScope}:{x}"; var policyValues = new List <string>() { $"{AppConstant.MicroServiceName}.{x}", $"{AppConstant.MicroServiceName}.{policyConfig.ControllerName}.all", $"{AppConstant.MicroServiceName}.all" }; options.AddPolicy(policyName, policy => policy.RequireClaim(PolicyKey.ClientScope, policyValues)); }); #endregion #region User的权限策略 policyConfig.Permissions.ForEach(x => { var policyName = $"{PolicyKey.UserPermission}:{x}"; var policyValues = new List <string>() { $"{AppConstant.MicroServiceName}.{x}", $"{AppConstant.MicroServiceName}.{policyConfig.ControllerName}.all", $"{AppConstant.MicroServiceName}.all" }; options.AddPolicy(policyName, policy => policy.RequireAssertion(handler => { var claim = handler.User.Claims .FirstOrDefault(c => c.Type.Equals(PolicyKey.UserPermission)); if (claim != null && !string.IsNullOrWhiteSpace(claim.Value)) { var claimValues = claim.Value.ToLower().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (claimValues != null && claimValues.Length > 0) { foreach (var item in claimValues) { if (policyValues.Contains(item)) { return(true); } } } } return(false); })); }); #endregion } }); } #endregion #region SwaggerGen if (Options.EnableSwaggerGen) { services.AddSwaggerGen(c => { c.EnableAnnotations(); //c.TagActionsBy(x => x.RelativePath.Split('/')[0]); c.AddSecurityDefinition("SubscriptionKey", new ApiKeyScheme() { Name = "Ocp-Apim-Subscription-Key", Type = "apiKey", In = "header", Description = "从开放平台申请的Subscription Key,从网关调用接口时必需传入。", }); c.AddSecurityDefinition("AccessToken", new ApiKeyScheme() { Name = "Authorization", Type = "apiKey", In = "header", Description = "从身份认证中心颁发的Token,根据接口要求决定是否传入。", }); c.AddSecurityDefinition("OAuth2", new OAuth2Scheme() { Type = "oauth2", Flow = "accessCode", AuthorizationUrl = Options.IdentityServerUri.OriginalString + "/connect/authorize", TokenUrl = Options.IdentityServerUri.OriginalString + "/connect/token", Description = "勾选授权范围,获取Token", Scopes = new Dictionary <string, string>() { { "openid", "用户标识" }, { "profile", "用户资料" }, { AppConstant.MicroServiceName + ".all", "所有接口权限" }, } }); var provider = services.BuildServiceProvider() .GetRequiredService <IApiVersionDescriptionProvider>(); foreach (var description in provider.ApiVersionDescriptions) { c.SwaggerDoc(description.GroupName, new Info { Title = AppConstant.AssemblyName, Version = description.ApiVersion.ToString(), License = new License() { Name = "MIT", Url = "https://spdx.org/licenses/MIT.html" }, // Contact = new Contact() // { // Url = "", // Name = "", // Email = "" // }, // Description = "Swagger document", }); c.CustomSchemaIds(x => x.FullName); } var SiteSwaggerFilePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, AppConstant.AssemblyName + ".xml"); if (File.Exists(SiteSwaggerFilePath)) { c.IncludeXmlComments(SiteSwaggerFilePath); } var ISMSSwaggerFilePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "IdentityServer4.MicroService.xml"); if (!File.Exists(ISMSSwaggerFilePath)) { using (var sw = new StreamWriter(ISMSSwaggerFilePath)) { sw.Write(AppResource.IdentityServer4_MicroService1); } } if (Options.EnableISMSSwaggerGen) { c.IncludeXmlComments(ISMSSwaggerFilePath); } }); } #endregion #region Localization if (Options.EnableLocalization) { builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); services.Configure <RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("zh-CN"), }; options.DefaultRequestCulture = new RequestCulture("zh-CN", "zh-CN"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); builder.Services.AddMvc() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization() .AddJsonOptions(o => { o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); } #endregion #region ApiVersioning if (Options.EnableApiVersioning) { builder.Services.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV"); builder.Services.AddApiVersioning(o => { o.AssumeDefaultVersionWhenUnspecified = true; o.ReportApiVersions = true; }); } #endregion #region Authentication builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(AppConstant.AppAuthenScheme, isAuth => { isAuth.Authority = configuration["IdentityServer:Host"]; isAuth.ApiName = AppConstant.MicroServiceName; isAuth.RequireHttpsMetadata = true; }) .AddIdentityServer4MicroServiceOAuths(configuration); #endregion #region ResponseCaching if (Options.EnableResponseCaching) { builder.Services.AddResponseCaching(); } #endregion var DBConnectionString = string.Empty; try { DBConnectionString = configuration["ConnectionStrings:DataBaseConnection"]; } catch { throw new KeyNotFoundException("appsettings.json文件,ConnectionStrings:DataBaseConnection"); } var DbContextOptions = new Action <DbContextOptionsBuilder>(x => x.UseSqlServer(DBConnectionString, opts => opts.MigrationsAssembly("IdentityServer4.MicroService"))); builder.AddCoreService(); builder.AddEmailService(configuration.GetSection("IdentityServer:Email")); builder.AddSmsService(configuration.GetSection("IdentityServer:SMS")); builder.AddTenantStore(DbContextOptions); builder.AddIdentityStore(DbContextOptions, Options.AspNetCoreIdentityOptions); builder.AddSqlCacheStore(DBConnectionString); var certificate = GetSigningCredential(configuration); builder.AddIdentityServer(DbContextOptions, certificate); builder.Services.AddMemoryCache(); return(builder); }
/// <summary> /// Creates a builder. /// </summary> /// <param name="services">The services.</param> /// <param name="ids4msOptions">The Options.</param> /// <param name="configuration">The Configuration.</param> /// <returns></returns> public static IId4MsServiceBuilder AddIdentityServer4MicroService( this IServiceCollection services, IdentityServer4MicroServiceOptions ids4msOptions, IConfiguration configuration) { var builder = services.AddIdentityServer4MicroServiceBuilder(); if (string.IsNullOrWhiteSpace(ids4msOptions.MicroServiceName)) { ids4msOptions.MicroServiceName = "ids4.ms"; } builder.Services.AddSingleton(ids4msOptions); #region Cors if (ids4msOptions.EnableCors) { builder.Services.AddCors(options => { options.AddPolicy("cors-allowanonymous", x => { x.AllowAnyHeader(); x.AllowAnyMethod(); x.AllowAnyOrigin(); x.AllowCredentials(); }); }); } #endregion #region WebEncoders if (ids4msOptions.WebEncoders) { services.AddWebEncoders(opt => { opt.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.All); }); } #endregion #region AuthorizationPolicy if (ids4msOptions.AuthorizationPolicy) { builder.Services.AddAuthorization(options => { #region Client的权限策略 var scopes = typeof(ClientScopes).GetFields(); foreach (var scope in scopes) { var scopeName = scope.GetRawConstantValue().ToString(); var scopeItem = scope.GetCustomAttribute <PolicyClaimValuesAttribute>(); var scopeValues = scopeItem.PolicyValues; var scopeValuesList = new List <string>(); for (var i = 0; i < scopeValues.Length; i++) { scopeValues[i] = ids4msOptions.MicroServiceName + "." + scopeValues[i]; scopeValuesList.Add(scopeValues[i]); } scopeValuesList.Add(ids4msOptions.MicroServiceName + "." + scopeItem.ControllerName + ".all"); scopeValuesList.Add(ids4msOptions.MicroServiceName + ".all"); options.AddPolicy(scopeName, policy => policy.RequireClaim(ClaimTypes.ClientScope, scopeValuesList)); } #endregion #region User的权限策略 var permissions = typeof(UserPermissions).GetFields(); foreach (var permission in permissions) { var permissionName = permission.GetRawConstantValue().ToString(); var permissionItem = permission.GetCustomAttribute <PolicyClaimValuesAttribute>(); var permissionValues = permissionItem.PolicyValues; var permissionValuesList = new List <string>(); for (var i = 0; i < permissionValues.Length; i++) { permissionValues[i] = ids4msOptions.MicroServiceName + "." + permissionValues[i]; permissionValuesList.Add(permissionValues[i]); } permissionValuesList.Add(ids4msOptions.MicroServiceName + "." + permissionItem.ControllerName + ".all"); permissionValuesList.Add(ids4msOptions.MicroServiceName + ".all"); options.AddPolicy(permissionName, policy => policy.RequireAssertion(context => { var userPermissionClaim = context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.UserPermission)); if (userPermissionClaim != null && !string.IsNullOrWhiteSpace(userPermissionClaim.Value)) { var userPermissionClaimValue = userPermissionClaim.Value.ToLower().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (userPermissionClaimValue != null && userPermissionClaimValue.Length > 0) { foreach (var userPermissionItem in userPermissionClaimValue) { if (permissionValuesList.Contains(userPermissionItem)) { return(true); } } } } return(false); })); } #endregion }); } #endregion #region SwaggerGen if (ids4msOptions.SwaggerGen) { services.AddSwaggerGen(c => { c.EnableAnnotations(); //c.TagActionsBy(x => x.RelativePath.Split('/')[0]); c.AddSecurityDefinition("SubscriptionKey", new ApiKeyScheme() { Name = "Ocp-Apim-Subscription-Key", Type = "apiKey", In = "header", Description = "从开放平台申请的Subscription Key,从网关调用接口时必需传入。", }); c.AddSecurityDefinition("AccessToken", new ApiKeyScheme() { Name = "Authorization", Type = "apiKey", In = "header", Description = "从身份认证中心颁发的Token,根据接口要求决定是否传入。", }); c.AddSecurityDefinition("OAuth2", new OAuth2Scheme() { Type = "oauth2", Flow = "accessCode", AuthorizationUrl = ids4msOptions.IdentityServer.OriginalString + "/connect/authorize", TokenUrl = ids4msOptions.IdentityServer.OriginalString + "/connect/token", Description = "勾选授权范围,获取Token", Scopes = new Dictionary <string, string>() { { "openid", "用户标识" }, { "profile", "用户资料" }, { ids4msOptions.MicroServiceName + ".all", "所有接口权限" }, } }); var provider = services.BuildServiceProvider() .GetRequiredService <IApiVersionDescriptionProvider>(); foreach (var description in provider.ApiVersionDescriptions) { c.SwaggerDoc(description.GroupName, new Info { Title = ids4msOptions.AssemblyName, Version = description.ApiVersion.ToString(), License = new License() { Name = "MIT", Url = "https://spdx.org/licenses/MIT.html" }, // Contact = new Contact() // { // Url = "", // Name = "", // Email = "" // }, // Description = "Swagger document", }); c.CustomSchemaIds(x => x.FullName); } var SiteSwaggerFilePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, ids4msOptions.AssemblyName + ".xml"); c.IncludeXmlComments(SiteSwaggerFilePath); var ISMSSwaggerFilePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "IdentityServer4.MicroService.xml"); if (!File.Exists(ISMSSwaggerFilePath)) { using (var sw = new StreamWriter(ISMSSwaggerFilePath)) { sw.Write(AppResource.IdentityServer4_MicroService1); } } c.IncludeXmlComments(ISMSSwaggerFilePath); }); } #endregion #region Localization if (ids4msOptions.Localization) { builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); services.Configure <RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("zh-CN"), }; options.DefaultRequestCulture = new RequestCulture("zh-CN", "zh-CN"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); builder.Services.AddMvc() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization() .AddJsonOptions(o => { o.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); } #endregion #region ApiVersioning if (ids4msOptions.ApiVersioning) { builder.Services.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV"); builder.Services.AddApiVersioning(o => { o.AssumeDefaultVersionWhenUnspecified = true; o.ReportApiVersions = true; }); } #endregion #region Authentication builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(AppConstant.AppAuthenScheme, isAuth => { isAuth.Authority = configuration["IdentityServer"]; isAuth.ApiName = ids4msOptions.MicroServiceName; isAuth.RequireHttpsMetadata = true; }) .AddIdentityServer4MicroServiceOAuths(configuration); #endregion #region ApiVersioning if (ids4msOptions.EnableResponseCaching) { builder.Services.AddResponseCaching(); } #endregion var DBConnectionString = configuration["ConnectionStrings:DataBaseConnection"]; var DbContextOptions = new Action <DbContextOptionsBuilder>(x => x.UseSqlServer(DBConnectionString, opts => opts.MigrationsAssembly("IdentityServer4.MicroService"))); builder .AddCoreService() .AddEmailService(configuration.GetSection("MessageSender:Email")) .AddSmsService(configuration.GetSection("MessageSender:Sms")); builder.AddTenantStore(DbContextOptions); builder.AddIdentityStore(DbContextOptions, ids4msOptions.IdentityOptions); builder.AddSqlCacheStore(DBConnectionString); builder.AddIdentityServer(DbContextOptions, configuration); builder.Services.AddMemoryCache(); return(builder); }