咨询Ocelot是否支持Cookie Authentication及API网关实现方案
问题解答
Ocelot完全支持Cookie Authentication,只是多数资料更侧重令牌类认证(如JWT),导致新手容易忽略这部分能力。以下是具体实现步骤:
1. 配置Cookie认证服务
在网关项目的Program.cs中,先添加Cookie认证服务和授权服务:
using Microsoft.AspNetCore.Authentication.Cookies; var builder = WebApplication.CreateBuilder(args); // 添加Cookie认证 builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/Account/Login"; // 未认证时跳转的登录接口 options.LogoutPath = "/Account/Logout"; options.ExpireTimeSpan = TimeSpan.FromHours(2); // Cookie有效期 options.SlidingExpiration = true; // 活动时自动延长有效期 // 跨域场景下可配置Domain属性,如options.Cookie.Domain = ".yourdomain.com"; }); // 添加授权服务 builder.Services.AddAuthorization(); // 添加Ocelot服务 builder.Services.AddOcelot(builder.Configuration); var app = builder.Build(); // 中间件顺序很重要:认证、授权必须在Ocelot之前 app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); // 启用Ocelot await app.UseOcelot(); app.Run();
2. 配置Ocelot路由规则
在ocelot.json中,为需要认证的微服务路由添加AuthenticationOptions,指定Cookie认证的ProviderKey:
{ "Routes": [ { "DownstreamPathTemplate": "/api/service1/{everything}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "service1.yourdomain.com", "Port": 443 } ], "UpstreamPathTemplate": "/service1/{everything}", "UpstreamHttpMethod": ["Get", "Post"], "AuthenticationOptions": { "AuthenticationProviderKey": "Cookies" // 对应Cookie认证的Scheme }, "AuthorizationOptions": { "AllowedRoles": ["Admin", "User"] // 可选:限制访问角色 } }, // 微服务2、3的路由配置类似 { "DownstreamPathTemplate": "/api/service2/{everything}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "service2.yourdomain.com", "Port": 443 } ], "UpstreamPathTemplate": "/service2/{everything}", "UpstreamHttpMethod": ["Get"], "AuthenticationOptions": { "AuthenticationProviderKey": "Cookies" } }, { "DownstreamPathTemplate": "/api/service3/{everything}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "service3.yourdomain.com", "Port": 443 } ], "UpstreamPathTemplate": "/service3/{everything}", "UpstreamHttpMethod": ["Post"], "AuthenticationOptions": { "AuthenticationProviderKey": "Cookies" } } ], "GlobalConfiguration": { "BaseUrl": "https://gateway.yourdomain.com" } }
3. 实现登录/登出逻辑(网关侧)
如果网关负责统一登录,编写登录接口验证用户后颁发Cookie:
[ApiController] [Route("Account")] public class AccountController : ControllerBase { [HttpPost("Login")] public async Task<IActionResult> Login([FromBody] LoginRequest request) { // 替换为实际的用户验证逻辑(如查询数据库) if (request.Username == "demo" && request.Password == "demo123") { var claims = new List<Claim> { new Claim(ClaimTypes.Name, request.Username), new Claim(ClaimTypes.Role, "User") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var authProps = new AuthenticationProperties { ExpiresUtc = DateTimeOffset.UtcNow.AddHours(2), IsPersistent = request.RememberMe }; await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), authProps); return Ok("登录成功"); } return Unauthorized("用户名或密码错误"); } [HttpPost("Logout")] public async Task<IActionResult> Logout() { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Ok("退出登录成功"); } } public class LoginRequest { public string Username { get; set; } public string Password { get; set; } public bool RememberMe { get; set; } }
注意事项
- 若网关与微服务跨域名部署,需配置Cookie的
Domain属性,确保Cookie能在域名间共享。 - 微服务侧若需获取用户身份信息,可通过网关转发的
HttpContext.User直接读取,无需重复认证。
内容的提问来源于stack exchange,提问作者Andrеw
相关产品推荐
相关产品推荐

