|
|
@ -34,206 +34,198 @@ using Volo.Abp.Modularity; |
|
|
using Volo.Abp.UI.Navigation.Urls; |
|
|
using Volo.Abp.UI.Navigation.Urls; |
|
|
using Volo.Abp.VirtualFileSystem; |
|
|
using Volo.Abp.VirtualFileSystem; |
|
|
|
|
|
|
|
|
namespace EShopOnAbp.AuthServer |
|
|
namespace EShopOnAbp.AuthServer; |
|
|
|
|
|
|
|
|
|
|
|
[DependsOn( |
|
|
|
|
|
typeof(AbpCachingStackExchangeRedisModule), |
|
|
|
|
|
typeof(AbpAspNetCoreAuthenticationJwtBearerModule), |
|
|
|
|
|
typeof(AbpEventBusRabbitMqModule), |
|
|
|
|
|
typeof(AbpBackgroundJobsRabbitMqModule), |
|
|
|
|
|
typeof(AbpAspNetCoreMvcUiBasicThemeModule), |
|
|
|
|
|
typeof(AbpAccountWebIdentityServerModule), |
|
|
|
|
|
typeof(AbpAccountHttpApiModule), |
|
|
|
|
|
typeof(AbpAccountApplicationModule), |
|
|
|
|
|
typeof(EShopOnAbpSharedHostingAspNetCoreModule), |
|
|
|
|
|
typeof(EShopOnAbpSharedLocalizationModule), |
|
|
|
|
|
typeof(AdministrationServiceEntityFrameworkCoreModule), |
|
|
|
|
|
typeof(IdentityServiceEntityFrameworkCoreModule) |
|
|
|
|
|
)] |
|
|
|
|
|
public class EShopOnAbpAuthServerModule : AbpModule |
|
|
{ |
|
|
{ |
|
|
[DependsOn( |
|
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
|
|
typeof(AbpCachingStackExchangeRedisModule), |
|
|
|
|
|
typeof(AbpAspNetCoreAuthenticationJwtBearerModule), |
|
|
|
|
|
typeof(AbpEventBusRabbitMqModule), |
|
|
|
|
|
typeof(AbpBackgroundJobsRabbitMqModule), |
|
|
|
|
|
typeof(AbpAspNetCoreMvcUiBasicThemeModule), |
|
|
|
|
|
typeof(AbpAccountWebIdentityServerModule), |
|
|
|
|
|
typeof(AbpAccountHttpApiModule), |
|
|
|
|
|
typeof(AbpAccountApplicationModule), |
|
|
|
|
|
typeof(EShopOnAbpSharedHostingAspNetCoreModule), |
|
|
|
|
|
typeof(EShopOnAbpSharedLocalizationModule), |
|
|
|
|
|
typeof(AdministrationServiceEntityFrameworkCoreModule), |
|
|
|
|
|
typeof(IdentityServiceEntityFrameworkCoreModule) |
|
|
|
|
|
)] |
|
|
|
|
|
public class EShopOnAbpAuthServerModule : AbpModule |
|
|
|
|
|
{ |
|
|
{ |
|
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
|
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|
|
{ |
|
|
|
|
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|
|
|
|
|
|
|
|
|
|
|
if (!hostingEnvironment.IsDevelopment()) |
|
|
|
|
|
{ |
|
|
|
|
|
var configuration = context.Services.GetConfiguration(); |
|
|
|
|
|
|
|
|
|
|
|
PreConfigure<AbpIdentityServerBuilderOptions>(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.AddDeveloperSigningCredential = false; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
PreConfigure<IIdentityServerBuilder>(builder => |
|
|
if (!hostingEnvironment.IsDevelopment()) |
|
|
{ |
|
|
|
|
|
builder.AddSigningCredential(GetSigningCertificate(hostingEnvironment)); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void ConfigureServices(ServiceConfigurationContext context) |
|
|
|
|
|
{ |
|
|
{ |
|
|
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; |
|
|
|
|
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|
|
|
|
|
var configuration = context.Services.GetConfiguration(); |
|
|
var configuration = context.Services.GetConfiguration(); |
|
|
|
|
|
|
|
|
ConfigureSwagger(context, configuration); |
|
|
PreConfigure<AbpIdentityServerBuilderOptions>(options => |
|
|
|
|
|
|
|
|
context.Services.AddAuthentication() |
|
|
|
|
|
.AddJwtBearer(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.Authority = configuration["AuthServer:Authority"]; |
|
|
|
|
|
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); |
|
|
|
|
|
options.Audience = "AccountService"; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
Configure<IdentityServerOptions>(options => |
|
|
|
|
|
{ |
|
|
{ |
|
|
options.IssuerUri = configuration["App:SelfUrl"]; |
|
|
options.AddDeveloperSigningCredential = false; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
Configure<AbpClaimsServiceOptions>(options => |
|
|
PreConfigure<IIdentityServerBuilder>(builder => |
|
|
{ |
|
|
|
|
|
options.RequestedClaims.AddRange(new[]{ |
|
|
|
|
|
EShopConstants.AnonymousUserClaimName |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
Configure<AbpAuditingOptions>(options => |
|
|
|
|
|
{ |
|
|
{ |
|
|
options.ApplicationName = "AuthServer"; |
|
|
builder.AddSigningCredential(GetSigningCertificate(hostingEnvironment)); |
|
|
}); |
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Configure<AppUrlOptions>(options => |
|
|
public override void ConfigureServices(ServiceConfigurationContext context) |
|
|
|
|
|
{ |
|
|
|
|
|
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; |
|
|
|
|
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|
|
|
|
|
var configuration = context.Services.GetConfiguration(); |
|
|
|
|
|
|
|
|
|
|
|
ConfigureSwagger(context, configuration); |
|
|
|
|
|
|
|
|
|
|
|
context.Services.AddAuthentication() |
|
|
|
|
|
.AddJwtBearer(options => |
|
|
{ |
|
|
{ |
|
|
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; |
|
|
options.Authority = configuration["AuthServer:Authority"]; |
|
|
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(',')); |
|
|
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); |
|
|
|
|
|
options.Audience = "AccountService"; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
Configure<AbpDistributedCacheOptions>(options => |
|
|
Configure<IdentityServerOptions>(options => { options.IssuerUri = configuration["App:SelfUrl"]; }); |
|
|
|
|
|
|
|
|
|
|
|
Configure<AbpClaimsServiceOptions>(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.RequestedClaims.AddRange(new[] |
|
|
{ |
|
|
{ |
|
|
options.KeyPrefix = "EShopOnAbp:"; |
|
|
EShopConstants.AnonymousUserClaimName |
|
|
}); |
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
Configure<AbpAuditingOptions>(options => { options.ApplicationName = "AuthServer"; }); |
|
|
|
|
|
|
|
|
|
|
|
Configure<AppUrlOptions>(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; |
|
|
|
|
|
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(',')); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
|
|
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "EShopOnAbp:"; }); |
|
|
context.Services |
|
|
|
|
|
.AddDataProtection() |
|
|
|
|
|
.PersistKeysToStackExchangeRedis(redis, "EShopOnAbp-Protection-Keys") |
|
|
|
|
|
.SetApplicationName("eShopOnAbp-AuthServer"); |
|
|
|
|
|
|
|
|
|
|
|
context.Services.AddCors(options => |
|
|
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
|
|
|
|
|
context.Services |
|
|
|
|
|
.AddDataProtection() |
|
|
|
|
|
.PersistKeysToStackExchangeRedis(redis, "EShopOnAbp-Protection-Keys") |
|
|
|
|
|
.SetApplicationName("eShopOnAbp-AuthServer"); |
|
|
|
|
|
|
|
|
|
|
|
context.Services.AddCors(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.AddDefaultPolicy(builder => |
|
|
{ |
|
|
{ |
|
|
options.AddDefaultPolicy(builder => |
|
|
builder |
|
|
{ |
|
|
.WithOrigins( |
|
|
builder |
|
|
configuration["App:CorsOrigins"] |
|
|
.WithOrigins( |
|
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|
|
configuration["App:CorsOrigins"] |
|
|
.Select(o => o.Trim().RemovePostFix("/")) |
|
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|
|
.ToArray() |
|
|
.Select(o => o.Trim().RemovePostFix("/")) |
|
|
) |
|
|
.ToArray() |
|
|
.WithAbpExposedHeaders() |
|
|
) |
|
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|
|
.WithAbpExposedHeaders() |
|
|
.AllowAnyHeader() |
|
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|
|
.AllowAnyMethod() |
|
|
.AllowAnyHeader() |
|
|
.AllowCredentials(); |
|
|
.AllowAnyMethod() |
|
|
|
|
|
.AllowCredentials(); |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
#if DEBUG
|
|
|
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>()); |
|
|
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>()); |
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
|
|
|
if (hostingEnvironment.IsDevelopment()) |
|
|
if (hostingEnvironment.IsDevelopment()) |
|
|
{ |
|
|
|
|
|
Configure<AbpVirtualFileSystemOptions>(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.FileSets.ReplaceEmbeddedByPhysical<EShopOnAbpSharedLocalizationModule>(Path.Combine(hostingEnvironment.ContentRootPath, |
|
|
|
|
|
$"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}shared{Path.DirectorySeparatorChar}EShopOnAbp.Shared.Localization")); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|
|
|
|
|
{ |
|
|
{ |
|
|
var app = context.GetApplicationBuilder(); |
|
|
Configure<AbpVirtualFileSystemOptions>(options => |
|
|
var env = context.GetEnvironment(); |
|
|
|
|
|
|
|
|
|
|
|
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>(); |
|
|
|
|
|
|
|
|
|
|
|
app.Use(async (ctx, next) => |
|
|
|
|
|
{ |
|
|
{ |
|
|
if (ctx.Request.Headers.ContainsKey("from-ingress")) |
|
|
options.FileSets.ReplaceEmbeddedByPhysical<EShopOnAbpSharedLocalizationModule>(Path.Combine( |
|
|
{ |
|
|
hostingEnvironment.ContentRootPath, |
|
|
ctx.SetIdentityServerOrigin(configuration["App:SelfUrl"]); |
|
|
$"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}shared{Path.DirectorySeparatorChar}EShopOnAbp.Shared.Localization")); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await next(); |
|
|
|
|
|
}); |
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (env.IsDevelopment()) |
|
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|
|
{ |
|
|
{ |
|
|
app.UseDeveloperExceptionPage(); |
|
|
var app = context.GetApplicationBuilder(); |
|
|
} |
|
|
var env = context.GetEnvironment(); |
|
|
|
|
|
|
|
|
app.UseAbpRequestLocalization(); |
|
|
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>(); |
|
|
|
|
|
|
|
|
if (!env.IsDevelopment()) |
|
|
app.Use(async (ctx, next) => |
|
|
|
|
|
{ |
|
|
|
|
|
if (ctx.Request.Headers.ContainsKey("from-ingress")) |
|
|
{ |
|
|
{ |
|
|
app.UseErrorPage(); |
|
|
ctx.SetIdentityServerOrigin(configuration["App:SelfUrl"]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
app.UseCorrelationId(); |
|
|
await next(); |
|
|
app.UseStaticFiles(); |
|
|
}); |
|
|
app.UseRouting(); |
|
|
|
|
|
app.UseCors(); |
|
|
if (env.IsDevelopment()) |
|
|
app.UseAuthentication(); |
|
|
|
|
|
app.UseJwtTokenMiddleware(); |
|
|
|
|
|
app.UseAbpSerilogEnrichers(); |
|
|
|
|
|
app.UseUnitOfWork(); |
|
|
|
|
|
app.UseIdentityServer(); |
|
|
|
|
|
app.UseAuthorization(); |
|
|
|
|
|
app.UseSwagger(); |
|
|
|
|
|
app.UseSwaggerUI(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Account Service API"); |
|
|
|
|
|
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); |
|
|
|
|
|
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); |
|
|
|
|
|
}); |
|
|
|
|
|
app.UseAuditing(); |
|
|
|
|
|
app.UseConfiguredEndpoints(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv) |
|
|
|
|
|
{ |
|
|
{ |
|
|
const string fileName = "eshoponabp-authserver.pfx"; |
|
|
app.UseDeveloperExceptionPage(); |
|
|
const string passPhrase = "780F3C11-0A96-40DE-B335-9848BE88C77D"; |
|
|
} |
|
|
var file = Path.Combine(hostingEnv.ContentRootPath, fileName); |
|
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(file)) |
|
|
app.UseAbpRequestLocalization(); |
|
|
{ |
|
|
|
|
|
throw new FileNotFoundException($"Signing Certificate couldn't found: {file}"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return new X509Certificate2(file, passPhrase); |
|
|
if (!env.IsDevelopment()) |
|
|
|
|
|
{ |
|
|
|
|
|
app.UseErrorPage(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration) |
|
|
app.UseCorrelationId(); |
|
|
|
|
|
app.UseStaticFiles(); |
|
|
|
|
|
app.UseRouting(); |
|
|
|
|
|
app.UseCors(); |
|
|
|
|
|
app.UseAuthentication(); |
|
|
|
|
|
app.UseJwtTokenMiddleware(); |
|
|
|
|
|
app.UseAbpSerilogEnrichers(); |
|
|
|
|
|
app.UseUnitOfWork(); |
|
|
|
|
|
app.UseIdentityServer(); |
|
|
|
|
|
app.UseAuthorization(); |
|
|
|
|
|
app.UseSwagger(); |
|
|
|
|
|
app.UseSwaggerUI(options => |
|
|
|
|
|
{ |
|
|
|
|
|
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Account Service API"); |
|
|
|
|
|
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); |
|
|
|
|
|
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); |
|
|
|
|
|
}); |
|
|
|
|
|
app.UseAuditing(); |
|
|
|
|
|
app.UseConfiguredEndpoints(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv) |
|
|
|
|
|
{ |
|
|
|
|
|
const string fileName = "eshoponabp-authserver.pfx"; |
|
|
|
|
|
const string passPhrase = "780F3C11-0A96-40DE-B335-9848BE88C77D"; |
|
|
|
|
|
var file = Path.Combine(hostingEnv.ContentRootPath, fileName); |
|
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(file)) |
|
|
{ |
|
|
{ |
|
|
SwaggerWithAuthConfigurationHelper.Configure( |
|
|
throw new FileNotFoundException($"Signing Certificate couldn't found: {file}"); |
|
|
context: context, |
|
|
} |
|
|
authority: configuration["AuthServer:Authority"], |
|
|
|
|
|
scopes: new Dictionary<string, string> |
|
|
return new X509Certificate2(file, passPhrase); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration) |
|
|
|
|
|
{ |
|
|
|
|
|
SwaggerWithAuthConfigurationHelper.Configure( |
|
|
|
|
|
context: context, |
|
|
|
|
|
authority: configuration["AuthServer:Authority"], |
|
|
|
|
|
scopes: new Dictionary<string, string> |
|
|
|
|
|
{ |
|
|
|
|
|
/* Requested scopes for authorization code request and descriptions for swagger UI only */ |
|
|
{ |
|
|
{ |
|
|
/* Requested scopes for authorization code request and descriptions for swagger UI only */ |
|
|
"AccountService", |
|
|
{ |
|
|
"Account Service API" |
|
|
"AccountService", |
|
|
|
|
|
"Account Service API" |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
}, |
|
|
apiTitle: "Account Service API" |
|
|
}, |
|
|
); |
|
|
apiTitle: "Account Service API" |
|
|
} |
|
|
); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |