diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs index 60338e6546..f7df64b257 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs @@ -45,7 +45,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client async () => await Proxy.Service.GetAsync(), () => new DistributedCacheEntryOptions { - AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) + AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(5) } ); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpConventionalControllerFeatureProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpConventionalControllerFeatureProvider.cs index e04574a03b..5347dca06a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpConventionalControllerFeatureProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Conventions/AbpConventionalControllerFeatureProvider.cs @@ -17,6 +17,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Conventions protected override bool IsController(TypeInfo typeInfo) { //TODO: Move this to a lazy loaded field for efficiency. + if (_application.ServiceProvider == null) + { + return false; + } + var configuration = _application.ServiceProvider .GetRequiredService>().Value .ConventionalControllers diff --git a/samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminAppHostModule.cs b/samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminAppHostModule.cs index 544b747a3c..bb6d884e57 100644 --- a/samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminAppHostModule.cs +++ b/samples/MicroserviceDemo/applications/BackendAdminApp.Host/BackendAdminAppHostModule.cs @@ -58,8 +58,9 @@ namespace BackendAdminApp.Host options.Scope.Add("role"); options.Scope.Add("email"); options.Scope.Add("phone"); + options.Scope.Add("InternalGateway"); options.Scope.Add("IdentityService"); - //options.Scope.Add("ProductService"); //TODO: Enable once available + options.Scope.Add("ProductService"); options.ClaimActions.MapAbpClaimTypes(); }); diff --git a/samples/MicroserviceDemo/applications/BackendAdminApp.Host/Controllers/TestController.cs b/samples/MicroserviceDemo/applications/BackendAdminApp.Host/Controllers/TestController.cs index bd51996add..f721560f02 100644 --- a/samples/MicroserviceDemo/applications/BackendAdminApp.Host/Controllers/TestController.cs +++ b/samples/MicroserviceDemo/applications/BackendAdminApp.Host/Controllers/TestController.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Json; namespace BackendAdminApp.Host.Controllers @@ -11,10 +13,12 @@ namespace BackendAdminApp.Host.Controllers public class TestController : AbpController { private readonly IJsonSerializer _jsonSerializer; + private readonly IPermissionChecker _permissionChecker; - public TestController(IJsonSerializer jsonSerializer) + public TestController(IJsonSerializer jsonSerializer, IPermissionChecker permissionChecker) { _jsonSerializer = jsonSerializer; + _permissionChecker = permissionChecker; } [HttpGet] @@ -24,7 +28,9 @@ namespace BackendAdminApp.Host.Controllers return Content( "Claims: " + User.Claims.Select(c => $"{c.Type} = {c.Value}").JoinAsString(" | ") + newLine + - "CurrentUser: " + _jsonSerializer.Serialize(CurrentUser) + newLine + "CurrentUser: " + _jsonSerializer.Serialize(CurrentUser) + newLine + + "access_token: " + await HttpContext.GetTokenAsync("access_token") + newLine + + "isGranted: AbpIdentity.Users: " + await _permissionChecker.IsGrantedAsync("AbpIdentity.Users") ); } } diff --git a/samples/MicroserviceDemo/applications/BackendAdminApp.Host/appsettings.json b/samples/MicroserviceDemo/applications/BackendAdminApp.Host/appsettings.json index 1d974b7937..35afa3c1e8 100644 --- a/samples/MicroserviceDemo/applications/BackendAdminApp.Host/appsettings.json +++ b/samples/MicroserviceDemo/applications/BackendAdminApp.Host/appsettings.json @@ -1,13 +1,7 @@ { "RemoteServices": { - "AbpIdentity": { - "BaseUrl": "http://localhost:63568/" - }, - "ProductManagement": { - "BaseUrl": "http://localhost:60244/" - }, - "AbpMvcClient": { - "BaseUrl": "http://localhost:63568/" + "Default": { + "BaseUrl": "http://localhost:65129/" } }, "Logging": { diff --git a/samples/MicroserviceDemo/applications/ConsoleClientDemo/ClientDemoService.cs b/samples/MicroserviceDemo/applications/ConsoleClientDemo/ClientDemoService.cs index 7525d7fb66..b7d6203609 100644 --- a/samples/MicroserviceDemo/applications/ConsoleClientDemo/ClientDemoService.cs +++ b/samples/MicroserviceDemo/applications/ConsoleClientDemo/ClientDemoService.cs @@ -2,7 +2,9 @@ using System; using System.Net.Http; using System.Threading.Tasks; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Identity; using Volo.Abp.IdentityModel; @@ -13,14 +15,17 @@ namespace ConsoleClientDemo private readonly IIdentityUserAppService _userAppService; private readonly IProductAppService _productAppService; private readonly IIdentityModelHttpClientAuthenticator _authenticator; + private readonly RemoteServiceOptions _remoteServiceOptions; public ClientDemoService( IIdentityUserAppService userAppService, IProductAppService productAppService, - IIdentityModelHttpClientAuthenticator authenticator) + IIdentityModelHttpClientAuthenticator authenticator, + IOptions remoteServiceOptions) { _userAppService = userAppService; _authenticator = authenticator; + _remoteServiceOptions = remoteServiceOptions.Value; _productAppService = productAppService; } @@ -46,7 +51,7 @@ namespace ConsoleClientDemo { await _authenticator.AuthenticateAsync(client); - var response = await client.GetAsync("http://localhost:63568/Test"); + var response = await client.GetAsync(_remoteServiceOptions.RemoteServices.Default.BaseUrl.EnsureEndsWith('/') + "Test"); if (!response.IsSuccessStatusCode) { Console.WriteLine(response.StatusCode); diff --git a/samples/MicroserviceDemo/applications/ConsoleClientDemo/ConsoleClientDemoModule.cs b/samples/MicroserviceDemo/applications/ConsoleClientDemo/ConsoleClientDemoModule.cs index b5e0e46faa..c69902ee19 100644 --- a/samples/MicroserviceDemo/applications/ConsoleClientDemo/ConsoleClientDemoModule.cs +++ b/samples/MicroserviceDemo/applications/ConsoleClientDemo/ConsoleClientDemoModule.cs @@ -14,6 +14,6 @@ namespace ConsoleClientDemo )] public class ConsoleClientDemoModule : AbpModule { - + } } diff --git a/samples/MicroserviceDemo/applications/ConsoleClientDemo/appsettings.json b/samples/MicroserviceDemo/applications/ConsoleClientDemo/appsettings.json index b1f3ecaf98..3817ac17ec 100644 --- a/samples/MicroserviceDemo/applications/ConsoleClientDemo/appsettings.json +++ b/samples/MicroserviceDemo/applications/ConsoleClientDemo/appsettings.json @@ -1,10 +1,7 @@ { "RemoteServices": { - "AbpIdentity": { - "BaseUrl": "http://localhost:63568/" - }, - "ProductManagement": { - "BaseUrl": "http://localhost:60244/" + "Default": { + "BaseUrl": "http://localhost:65129/" } }, "IdentityClients": { @@ -15,7 +12,7 @@ "UserName": "admin", "UserPassword": "1q2w3E*", "Authority": "http://localhost:64999", - "Scope": "IdentityService ProductService" + "Scope": "InternalGateway IdentityService ProductService" } } } \ No newline at end of file diff --git a/samples/MicroserviceDemo/databases/MsDemo_Identity.zip b/samples/MicroserviceDemo/databases/MsDemo_Identity.zip index 23997d7d67..b63d37c9c8 100644 Binary files a/samples/MicroserviceDemo/databases/MsDemo_Identity.zip and b/samples/MicroserviceDemo/databases/MsDemo_Identity.zip differ diff --git a/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGateway.Host.csproj b/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGateway.Host.csproj index 423afacffc..2ed06dc067 100644 --- a/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGateway.Host.csproj +++ b/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGateway.Host.csproj @@ -1,13 +1,46 @@ - + netcoreapp2.2 - InProcess + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + true + true + true + true + false + true - - + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGatewayHostModule.cs b/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGatewayHostModule.cs new file mode 100644 index 0000000000..b0bb455aa8 --- /dev/null +++ b/samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGatewayHostModule.cs @@ -0,0 +1,83 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Ocelot.DependencyInjection; +using Ocelot.Middleware; +using ProductManagement; +using Swashbuckle.AspNetCore.Swagger; +using Volo.Abp; +using Volo.Abp.Autofac; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Volo.Abp.Identity; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.Security.Claims; +using Volo.Abp.SettingManagement.EntityFrameworkCore; + +namespace InternalGateway.Host +{ + [DependsOn( + typeof(AbpAutofacModule), + typeof(AbpIdentityHttpApiModule), + typeof(ProductManagementHttpApiModule), + typeof(AbpEntityFrameworkCoreSqlServerModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule) + )] + public class InternalGatewayHostModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + //TODO: Internal gateway may not need to authentication in the gateway level, we may remove this when we complete and use the other gateways + + context.Services.AddAuthentication("Bearer") + .AddIdentityServerAuthentication(options => + { + options.Authority = "http://localhost:64999"; + options.RequireHttpsMetadata = false; + options.ApiName = "InternalGateway"; + + //TODO: Should create an extension method for that (may require to create a new ABP package depending on the IdentityServer4.AccessTokenValidation) + options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId; + options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role; + options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email; + options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified; + options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber; + options.InboundJwtClaimTypeMap["phone_number_verified"] = AbpClaimTypes.PhoneNumberVerified; + options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName; + }); + + context.Services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Info { Title = "Internal Gateway API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + }); + + context.Services.AddOcelot(context.Services.GetConfiguration()); + + Configure(options => + { + options.UseSqlServer(); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + + app.UseVirtualFiles(); + app.UseAuthentication(); + app.UseSwagger(); + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Internal Gateway API"); + }); + + app.MapWhen(ctx => ctx.Request.Path.ToString().StartsWith("/api/abp/") || ctx.Request.Path.ToString().StartsWith("/Abp/"), + app2 => { app2.UseMvcWithDefaultRouteAndArea(); }); + + app.UseOcelot().Wait(); + } + } +} diff --git a/samples/MicroserviceDemo/gateways/InternalGateway.Host/Program.cs b/samples/MicroserviceDemo/gateways/InternalGateway.Host/Program.cs index b67ed22456..719eaa6adb 100644 --- a/samples/MicroserviceDemo/gateways/InternalGateway.Host/Program.cs +++ b/samples/MicroserviceDemo/gateways/InternalGateway.Host/Program.cs @@ -1,24 +1,46 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; namespace InternalGateway.Host { public class Program { - public static void Main(string[] args) + public static int Main(string[] args) { - CreateWebHostBuilder(args).Build().Run(); + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.FromLogContext() + .WriteTo.File("Logs/logs.txt") + .CreateLogger(); + + try + { + Log.Information("Starting IdentityService.Host."); + BuildWebHostInternal(args).Run(); + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "IdentityService.Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); + public static IWebHost BuildWebHostInternal(string[] args) => + new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .UseSerilog() + .Build(); } } diff --git a/samples/MicroserviceDemo/gateways/InternalGateway.Host/Startup.cs b/samples/MicroserviceDemo/gateways/InternalGateway.Host/Startup.cs index 2546a72532..aed7ebbf4f 100644 --- a/samples/MicroserviceDemo/gateways/InternalGateway.Host/Startup.cs +++ b/samples/MicroserviceDemo/gateways/InternalGateway.Host/Startup.cs @@ -1,34 +1,28 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Volo.Abp; namespace InternalGateway.Host { public class Startup { - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) + public IServiceProvider ConfigureServices(IServiceCollection services) { + services.AddApplication(options => + { + options.UseAutofac(); + options.Configuration.UserSecretsAssembly = typeof(Startup).Assembly; + }); + + return services.BuildServiceProviderFromFactory(); } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.Run(async (context) => - { - await context.Response.WriteAsync("Hello World!"); - }); + app.InitializeApplication(); } } } diff --git a/samples/MicroserviceDemo/gateways/InternalGateway.Host/appsettings.json b/samples/MicroserviceDemo/gateways/InternalGateway.Host/appsettings.json index def9159a7d..22c9bddb71 100644 --- a/samples/MicroserviceDemo/gateways/InternalGateway.Host/appsettings.json +++ b/samples/MicroserviceDemo/gateways/InternalGateway.Host/appsettings.json @@ -1,4 +1,36 @@ { + "ConnectionStrings": { + "Default": "Server=localhost;Database=MsDemo_Identity;Trusted_Connection=True;MultipleActiveResultSets=true" + }, + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/identity/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 63568 + } + ], + "UpstreamPathTemplate": "/api/identity/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "DownstreamPathTemplate": "/api/productManagement/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 60244 + } + ], + "UpstreamPathTemplate": "/api/productManagement/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + } + ], + "GlobalConfiguration": { + "BaseUrl": "http://localhost:65129" + }, "Logging": { "LogLevel": { "Default": "Warning" diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.HttpApi/MyCompanyName/ProductManagement/ProductsController.cs b/samples/MicroserviceDemo/modules/product/src/ProductManagement.HttpApi/MyCompanyName/ProductManagement/ProductsController.cs index 9980c3a5a1..8ece86a0bd 100644 --- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.HttpApi/MyCompanyName/ProductManagement/ProductsController.cs +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.HttpApi/MyCompanyName/ProductManagement/ProductsController.cs @@ -31,7 +31,7 @@ namespace ProductManagement } [HttpGet] - [Route("/all")] + [Route("all")] public Task> GetListAsync() { return _productAppService.GetListAsync(); diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj index c253d73404..41161a3e36 100644 --- a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/ProductManagement.Web.csproj @@ -9,12 +9,14 @@ - + + +