From 0fb83d1a3cae0793110c5f8eb21dbbc7a7ad7e18 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Tue, 15 Dec 2020 16:33:50 +0800 Subject: [PATCH 1/4] Swagger UI: Set AntiForgeryToken every time --- .../Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js index 22277cb194..1c6f295c5b 100644 --- a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js +++ b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js @@ -2,6 +2,9 @@ (function () { abp.SwaggerUIBundle = function (configObject) { + + abp.setAntiForgeryToken(); + configObject.requestInterceptor = function (request) { var antiForgeryToken = abp.security.antiForgery.getToken(); @@ -13,4 +16,8 @@ return SwaggerUIBundle(configObject); } + + abp.setAntiForgeryToken = function(){ + fetch("/api/abp/application-configuration"); + } })(); From 78f5760563ed8ab34fac1bbe0bffc961e077c14e Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Tue, 15 Dec 2020 17:34:22 +0800 Subject: [PATCH 2/4] Added AbpSwashbuckleController --- .../Volo.Abp.Swashbuckle.csproj | 3 +- .../Swashbuckle/AbpSwashbuckleController.cs | 28 +++++++++++++++++++ .../Abp/Swashbuckle/AbpSwashbuckleModule.cs | 9 ++++-- .../wwwroot/swagger/ui/abp.swagger.js | 7 ++--- 4 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleController.cs diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj b/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj index e9d5e1afe5..5847dad4db 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj +++ b/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj @@ -4,7 +4,7 @@ - netstandard2.0 + net5 Volo.Abp.Swashbuckle Volo.Abp.Swashbuckle $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; @@ -19,6 +19,7 @@ + diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleController.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleController.cs new file mode 100644 index 0000000000..e115ea4b4e --- /dev/null +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleController.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.AntiForgery; +using Volo.Abp.Auditing; + +namespace Volo.Abp.Swashbuckle +{ + [Area("Abp")] + [Route("Abp/Swashbuckle/[action]")] + [DisableAuditing] + [RemoteService(false)] + [ApiExplorerSettings(IgnoreApi = true)] + public class AbpSwashbuckleController : AbpController + { + private readonly IAbpAntiForgeryManager _antiForgeryManager; + + public AbpSwashbuckleController(IAbpAntiForgeryManager antiForgeryManager) + { + _antiForgeryManager = antiForgeryManager; + } + + [HttpGet] + public void SetCsrfCookie() + { + _antiForgeryManager.SetCookie(); + } + } +} diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs index 949ac2ca2d..6f111bbc10 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs @@ -1,9 +1,14 @@ -using Volo.Abp.Modularity; +using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Swashbuckle { - [DependsOn(typeof(AbpVirtualFileSystemModule))] + [DependsOn( + typeof(AbpVirtualFileSystemModule), + typeof(AbpAspNetCoreMvcModule))] public class AbpSwashbuckleModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js index 1c6f295c5b..7c9c8bcc18 100644 --- a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js +++ b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js @@ -1,9 +1,10 @@ var abp = abp || {}; (function () { + abp.SwaggerUIBundle = function (configObject) { - abp.setAntiForgeryToken(); + fetch("/abp/Swashbuckle/SetCsrfCookie"); configObject.requestInterceptor = function (request) { @@ -16,8 +17,4 @@ return SwaggerUIBundle(configObject); } - - abp.setAntiForgeryToken = function(){ - fetch("/api/abp/application-configuration"); - } })(); From 2809226a4471b9b4987b4858b222e49a30065455 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Tue, 15 Dec 2020 17:58:03 +0800 Subject: [PATCH 3/4] Update abp.swagger.js --- .../src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js index 7c9c8bcc18..709d6c2a3c 100644 --- a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js +++ b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js @@ -4,7 +4,7 @@ abp.SwaggerUIBundle = function (configObject) { - fetch("/abp/Swashbuckle/SetCsrfCookie"); + fetch(`${abp.appPath}abp/Swashbuckle/SetCsrfCookie`); configObject.requestInterceptor = function (request) { From 237dbb1f6ac1af633950935c34741f915013e8c2 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Wed, 16 Dec 2020 20:14:48 +0800 Subject: [PATCH 4/4] Improved --- .../Builder/AbpSwaggerUIBuilderExtensions.cs | 2 +- .../Volo.Abp.Swashbuckle.csproj | 2 + .../Abp/Swashbuckle/AbpSwashbuckleModule.cs | 4 +- .../wwwroot/swagger/ui/abp.js | 97 +++++++++++++++++++ .../wwwroot/swagger/ui/abp.swagger.js | 18 +++- .../MyProjectNameHttpApiHostModule.cs | 2 +- 6 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.js diff --git a/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs b/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs index 4a54191459..0f19345038 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Microsoft/AspNetCore/Builder/AbpSwaggerUIBuilderExtensions.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Builder return app.UseSwaggerUI(options => { - options.InjectJavascript("/libs/abp/core/abp.js"); + options.InjectJavascript("/swagger/ui/abp.js"); options.InjectJavascript("/swagger/ui/abp.swagger.js"); options.IndexStream = () => resolver.Resolver(); diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj b/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj index 5847dad4db..9a720524d9 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj +++ b/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj @@ -26,6 +26,8 @@ + + diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs index 6f111bbc10..c8ee0737c8 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleModule.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Mvc.ApplicationParts; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; diff --git a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.js b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.js new file mode 100644 index 0000000000..0e13317cbf --- /dev/null +++ b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.js @@ -0,0 +1,97 @@ +var abp = abp || {}; +(function () { + + /* Application paths *****************************************/ + + //Current application root path (including virtual directory if exists). + abp.appPath = abp.appPath || '/'; + + /* UTILS ***************************************************/ + + abp.utils = abp.utils || {}; + + /** + * Sets a cookie value for given key. + * This is a simple implementation created to be used by ABP. + * Please use a complete cookie library if you need. + * @param {string} key + * @param {string} value + * @param {Date} expireDate (optional). If not specified the cookie will expire at the end of session. + * @param {string} path (optional) + */ + abp.utils.setCookieValue = function (key, value, expireDate, path) { + var cookieValue = encodeURIComponent(key) + '='; + + if (value) { + cookieValue = cookieValue + encodeURIComponent(value); + } + + if (expireDate) { + cookieValue = cookieValue + "; expires=" + expireDate.toUTCString(); + } + + if (path) { + cookieValue = cookieValue + "; path=" + path; + } + + document.cookie = cookieValue; + }; + + /** + * Gets a cookie with given key. + * This is a simple implementation created to be used by ABP. + * Please use a complete cookie library if you need. + * @param {string} key + * @returns {string} Cookie value or null + */ + abp.utils.getCookieValue = function (key) { + var equalities = document.cookie.split('; '); + for (var i = 0; i < equalities.length; i++) { + if (!equalities[i]) { + continue; + } + + var splitted = equalities[i].split('='); + if (splitted.length != 2) { + continue; + } + + if (decodeURIComponent(splitted[0]) === key) { + return decodeURIComponent(splitted[1] || ''); + } + } + + return null; + }; + + /** + * Deletes cookie for given key. + * This is a simple implementation created to be used by ABP. + * Please use a complete cookie library if you need. + * @param {string} key + * @param {string} path (optional) + */ + abp.utils.deleteCookie = function (key, path) { + var cookieValue = encodeURIComponent(key) + '='; + + cookieValue = cookieValue + "; expires=" + (new Date(new Date().getTime() - 86400000)).toUTCString(); + + if (path) { + cookieValue = cookieValue + "; path=" + path; + } + + document.cookie = cookieValue; + } + + /* SECURITY ***************************************/ + abp.security = abp.security || {}; + abp.security.antiForgery = abp.security.antiForgery || {}; + + abp.security.antiForgery.tokenCookieName = 'XSRF-TOKEN'; + abp.security.antiForgery.tokenHeaderName = 'RequestVerificationToken'; + + abp.security.antiForgery.getToken = function () { + return abp.utils.getCookieValue(abp.security.antiForgery.tokenCookieName); + }; + +})(); diff --git a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js index 709d6c2a3c..ac85cf2559 100644 --- a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js +++ b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js @@ -4,9 +4,23 @@ abp.SwaggerUIBundle = function (configObject) { - fetch(`${abp.appPath}abp/Swashbuckle/SetCsrfCookie`); + var excludeUrl = ["swagger.json", "connect/token"] + var firstRequest = true; + abp.appPath = configObject.baseUrl || abp.appPath; - configObject.requestInterceptor = function (request) { + configObject.requestInterceptor = async function (request) { + + if(request.url.includes(excludeUrl[1])){ + firstRequest = true; + } + + if(firstRequest && !excludeUrl.some(url => request.url.includes(url))) + { + await fetch(`${abp.appPath}abp/Swashbuckle/SetCsrfCookie`,{ + headers: request.headers + }); + firstRequest = false; + } var antiForgeryToken = abp.security.antiForgery.getToken(); if (antiForgeryToken) { diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs index e099b22391..328722915e 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs @@ -207,7 +207,7 @@ namespace MyCompanyName.MyProjectName app.UseAuthorization(); app.UseSwagger(); - app.UseSwaggerUI(options => + app.UseAbpSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API");