do not use powcapserver.aspnetcore package; use api controller for captcha endpoints
This commit is contained in:
@@ -8,6 +8,13 @@ public static class ApplicationBuilderExtensions
|
||||
{
|
||||
app.UseMiddleware<ZeroContextMiddleware>();
|
||||
app.UseOutputCache();
|
||||
|
||||
if (app is WebApplication webApplication)
|
||||
{
|
||||
webApplication.MapRazorPages();
|
||||
webApplication.MapControllers();
|
||||
}
|
||||
|
||||
ZeroBuilder.Modules.Configure(app, null, app.ApplicationServices);
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PowCapServer.Abstractions;
|
||||
using PowCapServer.Models;
|
||||
using zero.Mvc;
|
||||
|
||||
namespace zero.Security;
|
||||
|
||||
[ApiController]
|
||||
[Route("/api/captcha")]
|
||||
public class CaptchaController(ICaptchaService captchaService) : ZeroController
|
||||
{
|
||||
[HttpPost("challenge")]
|
||||
public async Task<IActionResult> PostChallenge()
|
||||
{
|
||||
ChallengeTokenInfo challengeTokenInfo = await captchaService.CreateChallengeAsync(HttpContext.RequestAborted);
|
||||
return Json(challengeTokenInfo);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("{useCase}/challenge")]
|
||||
public async Task<IActionResult> PostChallengeWithUseCase(string useCase)
|
||||
{
|
||||
ChallengeTokenInfo challengeTokenInfo = await captchaService.CreateChallengeAsync(useCase, HttpContext.RequestAborted);
|
||||
return Json(challengeTokenInfo);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("redeem")]
|
||||
public async Task<IActionResult> PostRedeem(ChallengeSolution model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
RedeemChallengeResult result = await captchaService.RedeemChallengeAsync(model).ConfigureAwait(false);
|
||||
return Json(result);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("{useCase}/redeem")]
|
||||
public async Task<IActionResult> PostRedeemWithUseCase(string useCase, ChallengeSolution model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
RedeemChallengeResult result = await captchaService.RedeemChallengeAsync(useCase, model).ConfigureAwait(false);
|
||||
return Json(result);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("cap.wasm")]
|
||||
public IActionResult GetWasmFile()
|
||||
{
|
||||
Assembly assembly = typeof(ZeroSecurityModule).GetTypeInfo().Assembly;
|
||||
Stream resource = assembly.GetManifestResourceStream("zero.Resources.cap_wasm_bg_0_0_6.wasm");
|
||||
|
||||
if (resource is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return File(resource, "application/wasm");
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("cap.widget.js")]
|
||||
public IActionResult GetWidgetJsFile()
|
||||
{
|
||||
Assembly assembly = typeof(ZeroSecurityModule).GetTypeInfo().Assembly;
|
||||
Stream resource = assembly.GetManifestResourceStream("zero.Resources.cap_min_0_1_41.js");
|
||||
|
||||
if (resource is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return File(resource, "text/javascript");
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ using zero.Security;
|
||||
|
||||
namespace zero.TagHelpers;
|
||||
|
||||
[HtmlTargetElement("app-captcha", Attributes = "for,lang", TagStructure = TagStructure.NormalOrSelfClosing)]
|
||||
[HtmlTargetElement("app-captcha", Attributes = "for", TagStructure = TagStructure.NormalOrSelfClosing)]
|
||||
public class CaptchaTagHelper(IOptionsMonitor<CaptchaOptions> options) : TagHelper
|
||||
{
|
||||
[HtmlAttributeNotBound]
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using PowCapServer;
|
||||
using PowCapServer.Abstractions;
|
||||
|
||||
namespace zero.Security;
|
||||
|
||||
@@ -14,60 +13,25 @@ internal class ZeroSecurityModule : ZeroModule
|
||||
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
IConfigurationSection captchaSection = configuration.GetSection("Zero:Captcha");
|
||||
services.AddOptions<CaptchaOptions>().Bind(captchaSection);
|
||||
|
||||
services.AddPowCapServer(options =>
|
||||
{
|
||||
CaptchaOptions captchaOptions = captchaSection.Get<CaptchaOptions>() ?? new CaptchaOptions();
|
||||
options.Default = captchaOptions;
|
||||
});
|
||||
services.TryAddSingleton<ICaptchaService, DefaultCaptchaService>();
|
||||
services.TryAddSingleton<ICaptchaStore, DefaultCaptchaStore>();
|
||||
services.TryAddTransient<ISerializer, DefaultSerializer>();
|
||||
services.Configure<PowCapServerOptions>(opts => opts.Default = captchaSection.Get<CaptchaOptions>() ?? new CaptchaOptions());
|
||||
services.AddOptions<CaptchaOptions>().Bind(captchaSection);
|
||||
}
|
||||
|
||||
public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
|
||||
{
|
||||
IOptionsMonitor<CaptchaOptions> options = serviceProvider.GetRequiredService<IOptionsMonitor<CaptchaOptions>>();
|
||||
string endpointPrefix = options.CurrentValue.Endpoint;
|
||||
// if (app is WebApplication webApp)
|
||||
// {
|
||||
// webApp.MapGet("/teamup/sync", async (ISchedulerFactory scheduler) =>
|
||||
// {
|
||||
// await SyncTeamUpDataJob.RunNow(scheduler);
|
||||
// return "done";
|
||||
// });
|
||||
// }
|
||||
|
||||
app.UseRouting();
|
||||
app.MapPowCapServer(endpointPrefix);
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapGet(endpointPrefix + "/cap.wasm", async context =>
|
||||
{
|
||||
Assembly assembly = typeof(ZeroSecurityModule).GetTypeInfo().Assembly;
|
||||
Stream resource = assembly.GetManifestResourceStream("zero.Resources.cap_wasm_bg_0_0_6.wasm");
|
||||
|
||||
if (resource is null)
|
||||
{
|
||||
context.Response.StatusCode = StatusCodes.Status404NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
await using (resource)
|
||||
{
|
||||
context.Response.ContentType = "application/wasm";
|
||||
await resource.CopyToAsync(context.Response.Body, context.RequestAborted);
|
||||
}
|
||||
});
|
||||
|
||||
endpoints.MapGet(endpointPrefix + "/cap.widget.js", async context =>
|
||||
{
|
||||
Assembly assembly = typeof(ZeroSecurityModule).GetTypeInfo().Assembly;
|
||||
Stream resource = assembly.GetManifestResourceStream("zero.Resources.cap_min_0_1_41.js");
|
||||
|
||||
if (resource is null)
|
||||
{
|
||||
context.Response.StatusCode = StatusCodes.Status404NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
await using (resource)
|
||||
{
|
||||
context.Response.ContentType = "text/javascript";
|
||||
await resource.CopyToAsync(context.Response.Body, context.RequestAborted);
|
||||
}
|
||||
});
|
||||
});
|
||||
StaticCaptchaService.Configure(serviceProvider);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="9.0.4" />
|
||||
<PackageReference Include="FluentValidation" Version="11.11.0" />
|
||||
<PackageReference Include="Postmark" Version="5.3.0" />
|
||||
<PackageReference Include="PowCapServer.AspNetCore" Version="2.0.0" />
|
||||
<PackageReference Include="PowCapServer.Core" Version="2.0.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user