Browse Source

Merge pull request #6124 from abpframework/liangshiwei/swagger-auth

Enable swagger OAuth2 for IDS and API Host projects
pull/6134/head
maliming 6 years ago
committed by GitHub
parent
commit
845402eb62
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs
  2. 54
      framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenServiceCollectionExtensions.cs
  3. 3
      framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js
  4. 5
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/appsettings.json
  5. 18
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/IdentityServer/IdentityServerDataSeedContributor.cs
  6. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj
  7. 27
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
  8. 6
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json
  9. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj
  10. 15
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs
  11. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/appsettings.json
  12. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj
  13. 21
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs
  14. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json
  15. 18
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/IdentityServer/IdentityServerDataSeedContributor.cs
  16. 7
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/appsettings.json

1
framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs

@ -1,7 +1,6 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.SwaggerUI;
using Volo.Abp;
using Volo.Abp.Swashbuckle;
namespace Microsoft.AspNetCore.Builder

54
framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenServiceCollectionExtensions.cs

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Microsoft.Extensions.DependencyInjection
{
public static class AbpSwaggerGenServiceCollectionExtensions
{
public static IServiceCollection AddAbpSwaggerGenWithOAuth(
this IServiceCollection services,
[NotNull] string authority,
[NotNull] Dictionary<string, string> scopes,
Action<SwaggerGenOptions> setupAction = null)
{
return services.AddSwaggerGen(
options =>
{
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri($"{authority.EnsureEndsWith('/')}connect/authorize"),
Scopes = scopes,
TokenUrl = new Uri($"{authority.EnsureEndsWith('/')}connect/token")
}
}
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "oauth2"
}
},
Array.Empty<string>()
}
});
setupAction?.Invoke(options);
});
}
}
}

3
framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js

@ -3,8 +3,7 @@
(function () {
abp.SwaggerUIBundle = function (configObject) {
configObject.requestInterceptor = function (request) {
var token = abp.auth.getToken();
request.headers.Authorization = token ? "Bearer " + token : null;
var antiForgeryToken = abp.security.antiForgery.getToken();
if (antiForgeryToken) {
request.headers[abp.security.antiForgery.tokenHeaderName] = antiForgeryToken;

5
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/appsettings.json

@ -17,6 +17,11 @@
"MyProjectName_Blazor": {
"ClientId": "MyProjectName_Blazor",
"RootUrl": "https://localhost:44307"
},
"MyProjectName_Swagger": {
"ClientId": "MyProjectName_Swagger",
"ClientSecret": "1q2w3e*",
"RootUrl": "https://localhost:44300"
}
}
}

18
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain/IdentityServer/IdentityServerDataSeedContributor.cs

@ -188,6 +188,22 @@ namespace MyCompanyName.MyProjectName.IdentityServer
postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback"
);
}
// Swagger Client
var swaggerClientId = configurationSection["MyProjectName_Swagger:ClientId"];
if (!swaggerClientId.IsNullOrWhiteSpace())
{
var swaggerRootUrl = configurationSection["MyProjectName_Swagger:RootUrl"].TrimEnd('/');
await CreateClientAsync(
name: swaggerClientId,
scopes: commonScopes,
grantTypes: new[] { "authorization_code" },
secret: configurationSection["MyProjectName_Swagger:ClientSecret"]?.Sha256(),
requireClientSecret: false,
redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html"
);
}
}
private async Task<Client> CreateClientAsync(
@ -281,4 +297,4 @@ namespace MyCompanyName.MyProjectName.IdentityServer
return await _clientRepository.UpdateAsync(client);
}
}
}
}

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj

@ -12,7 +12,6 @@
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0-rc.2.*" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="5.0.0-rc.2.*" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-rc.2.*" />
@ -20,6 +19,7 @@
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Caching.StackExchangeRedis\Volo.Abp.Caching.StackExchangeRedis.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Swashbuckle\Volo.Abp.Swashbuckle.csproj" />
</ItemGroup>
<ItemGroup>

27
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Authentication.JwtBearer;
@ -23,6 +24,7 @@ using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Volo.Abp.VirtualFileSystem;
namespace MyCompanyName.MyProjectName
@ -34,7 +36,8 @@ namespace MyCompanyName.MyProjectName
typeof(AbpAspNetCoreMvcUiMultiTenancyModule),
typeof(MyProjectNameApplicationModule),
typeof(MyProjectNameEntityFrameworkCoreDbMigrationsModule),
typeof(AbpAspNetCoreSerilogModule)
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule)
)]
public class MyProjectNameHttpApiHostModule : AbpModule
{
@ -52,7 +55,7 @@ namespace MyCompanyName.MyProjectName
ConfigureVirtualFileSystem(context);
ConfigureRedis(context, configuration, hostingEnvironment);
ConfigureCors(context, configuration);
ConfigureSwaggerServices(context);
ConfigureSwaggerServices(context, configuration);
}
private void ConfigureCache(IConfiguration configuration)
@ -103,9 +106,14 @@ namespace MyCompanyName.MyProjectName
});
}
private static void ConfigureSwaggerServices(ServiceConfigurationContext context)
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddSwaggerGen(
context.Services.AddAbpSwaggerGenWithOAuth(
configuration["AuthServer:Authority"],
new Dictionary<string, string>
{
{"MyProjectName", "MyProjectName API"}
},
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo {Title = "MyProjectName API", Version = "v1"});
@ -198,11 +206,18 @@ namespace MyCompanyName.MyProjectName
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API"); });
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API");
var configuration = context.GetConfiguration();
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
}
}
}
}

6
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json

@ -10,8 +10,10 @@
},
"AuthServer": {
"Authority": "https://localhost:44301",
"RequireHttpsMetadata": "true"
},
"RequireHttpsMetadata": "true",
"SwaggerClientId": "MyProjectName_Swagger",
"SwaggerClientSecret": "1q2w3e*"
},
"StringEncryption": {
"DefaultPassPhrase": "gsKnGZ041HLL4IM8"
},

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj

@ -19,6 +19,7 @@
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Authentication.JwtBearer\Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Swashbuckle\Volo.Abp.Swashbuckle.csproj" />
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.Web.IdentityServer\Volo.Abp.Account.Web.IdentityServer.csproj" />
</ItemGroup>

15
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
@ -23,6 +24,7 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
@ -37,7 +39,8 @@ namespace MyCompanyName.MyProjectName
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpAccountWebIdentityServerModule),
typeof(AbpAspNetCoreSerilogModule)
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule)
)]
public class MyProjectNameHttpApiHostModule : AbpModule
{
@ -64,10 +67,7 @@ namespace MyCompanyName.MyProjectName
{
options.StyleBundles.Configure(
BasicThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
bundle => { bundle.AddFiles("/global-styles.css"); }
);
});
}
@ -211,7 +211,10 @@ namespace MyCompanyName.MyProjectName
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API"); });
app.UseAbpSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API");
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/appsettings.json

@ -1,7 +1,7 @@
{
"App": {
"SelfUrl": "https://localhost:44301",
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:4200,https://localhost:44307"
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:4200,https://localhost:44307,https://localhost:44300"
},
"ConnectionStrings": {
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=MyProjectName;Trusted_Connection=True;MultipleActiveResultSets=true"

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj

@ -12,7 +12,6 @@
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
<PackageReference Include="IdentityModel" Version="4.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0-rc.2.*" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="5.0.0-rc.2.*" />
@ -22,6 +21,7 @@
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.EntityFrameworkCore.SqlServer\Volo.Abp.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj" />
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Swashbuckle\Volo.Abp.Swashbuckle.csproj" />
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.EntityFrameworkCore\Volo.Abp.SettingManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\..\..\modules\audit-logging\src\Volo.Abp.AuditLogging.EntityFrameworkCore\Volo.Abp.AuditLogging.EntityFrameworkCore.csproj" />

21
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs

@ -2,21 +2,19 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using IdentityModel;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MyCompanyName.MyProjectName.EntityFrameworkCore;
using MyCompanyName.MyProjectName.MultiTenancy;
using StackExchange.Redis;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using Volo.Abp;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Serilog;
@ -32,6 +30,7 @@ using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Swashbuckle;
using Volo.Abp.VirtualFileSystem;
namespace MyCompanyName.MyProjectName
@ -47,7 +46,8 @@ namespace MyCompanyName.MyProjectName
typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpAspNetCoreSerilogModule)
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule)
)]
public class MyProjectNameHttpApiHostModule : AbpModule
{
@ -79,10 +79,15 @@ namespace MyCompanyName.MyProjectName
});
}
context.Services.AddSwaggerGen(
context.Services.AddAbpSwaggerGenWithOAuth(
configuration["AuthServer:Authority"],
new Dictionary<string, string>
{
{"MyProjectName", "MyProjectName API"}
},
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "MyProjectName API", Version = "v1" });
options.SwaggerDoc("v1", new OpenApiInfo {Title = "MyProjectName API", Version = "v1"});
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
});
@ -179,6 +184,10 @@ namespace MyCompanyName.MyProjectName
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API");
var configuration = context.GetConfiguration();
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json

@ -11,6 +11,8 @@
},
"AuthServer": {
"Authority": "https://localhost:44301/",
"RequireHttpsMetadata": "false"
"RequireHttpsMetadata": "false",
"SwaggerClientId": "MyProjectName_Swagger",
"SwaggerClientSecret": "1q2w3e*"
}
}

18
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/IdentityServer/IdentityServerDataSeedContributor.cs

@ -166,7 +166,7 @@ namespace MyCompanyName.MyProjectName.IdentityServer
secret: (configurationSection["MyProjectName_ConsoleTestApp:ClientSecret"] ?? "1q2w3e*").Sha256()
);
}
// Blazor Client
var blazorClientId = configurationSection["MyProjectName_Blazor:ClientId"];
if (!blazorClientId.IsNullOrWhiteSpace())
@ -183,6 +183,22 @@ namespace MyCompanyName.MyProjectName.IdentityServer
postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback"
);
}
// Swagger Client
var swaggerClientId = configurationSection["MyProjectName_Swagger:ClientId"];
if (!swaggerClientId.IsNullOrWhiteSpace())
{
var swaggerRootUrl = configurationSection["MyProjectName_Swagger:RootUrl"].TrimEnd('/');
await CreateClientAsync(
name: swaggerClientId,
scopes: commonScopes,
grantTypes: new[] { "authorization_code" },
secret: configurationSection["MyProjectName_Swagger:ClientSecret"]?.Sha256(),
requireClientSecret: false,
redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html"
);
}
}
private async Task<Client> CreateClientAsync(

7
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/appsettings.json

@ -1,7 +1,7 @@
{
"App": {
"SelfUrl": "https://localhost:44301/",
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:4200,http://localhost:44307,https://localhost:44307"
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:4200,http://localhost:44307,https://localhost:44307,https://localhost:44300"
},
"AppSelfUrl": "https://localhost:44301/",
"ConnectionStrings": {
@ -27,6 +27,11 @@
},
"MyProjectName_ConsoleTestApp": {
"ClientId": "MyProjectName_ConsoleTestApp"
},
"MyProjectName_Swagger": {
"ClientId": "MyProjectName_Swagger",
"ClientSecret": "1q2w3e*",
"RootUrl": "https://localhost:44300"
}
}
}

Loading…
Cancel
Save