diff --git a/src/UIs/bff/ReverseProxy.Yarp/Controllers/AuthenticationController.cs b/src/UIs/bff/ReverseProxy.Yarp/Controllers/AuthenticationController.cs index 8116861fb..78be562eb 100644 --- a/src/UIs/bff/ReverseProxy.Yarp/Controllers/AuthenticationController.cs +++ b/src/UIs/bff/ReverseProxy.Yarp/Controllers/AuthenticationController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Antiforgery; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Mvc; @@ -7,6 +8,13 @@ namespace ReverseProxy.Yarp.Controllers { public class AuthenticationController : ControllerBase { + private readonly IAntiforgery _forgeryService; + + public AuthenticationController(IAntiforgery forgeryService) + { + _forgeryService = forgeryService; + } + [HttpGet("/login")] public async Task LoginAsync(string returnUrl) { @@ -35,6 +43,9 @@ public IActionResult UserInfor() { if (HttpContext.User.Identity?.IsAuthenticated ?? false) { + var tokens = _forgeryService.GetAndStoreTokens(HttpContext); + HttpContext.Response.Cookies.Append("PHONG-XSRF-TOKEN", tokens.RequestToken!, new CookieOptions { HttpOnly = false }); + return Ok(new { Id = "", diff --git a/src/UIs/bff/ReverseProxy.Yarp/Program.cs b/src/UIs/bff/ReverseProxy.Yarp/Program.cs index 0e4fd3734..4de567602 100644 --- a/src/UIs/bff/ReverseProxy.Yarp/Program.cs +++ b/src/UIs/bff/ReverseProxy.Yarp/Program.cs @@ -1,8 +1,10 @@ +using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using ReverseProxy.Yarp.ConfigurationOptions; +using System.Net; using System.Net.Http.Headers; using Yarp.ReverseProxy.Transforms; @@ -37,6 +39,8 @@ public static void Main(string[] args) services.AddControllers(); + services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); + services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; @@ -66,6 +70,25 @@ public static void Main(string[] args) app.MapControllers(); + app.Use(async (context, next) => + { + if (context.Request.Path.Value?.StartsWith("/api/", StringComparison.OrdinalIgnoreCase) ?? false) + { + try + { + var antiForgeryService = context.RequestServices.GetRequiredService(); + await antiForgeryService.ValidateRequestAsync(context); + } + catch (AntiforgeryValidationException) + { + context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; + return; + } + } + + await next(context); + }); + app.MapReverseProxy(); app.MapForwarder("{**rest}", "http://localhost:3000"); diff --git a/src/UIs/bff/reactjs/src/containers/Auth/authInterceptors.tsx b/src/UIs/bff/reactjs/src/containers/Auth/authInterceptors.tsx index 7c1eea15a..cd27b8c84 100644 --- a/src/UIs/bff/reactjs/src/containers/Auth/authInterceptors.tsx +++ b/src/UIs/bff/reactjs/src/containers/Auth/authInterceptors.tsx @@ -2,6 +2,11 @@ import { login, logout } from "./authService"; const addAuthInterceptors = (axios) => { axios.interceptors.request.use((config) => { + const xsrfToken = document + .cookie!.split("; ")! + .find((row) => row.startsWith("PHONG-XSRF-TOKEN="))! + .split("=")[1]; + config.headers["X-XSRF-TOKEN"] = xsrfToken; return config; }); axios.interceptors.response.use(