.NET Core 2.1 Razor项目API控制器无法获取已登录用户问题
Hey there, let's work through this issue together— I've run into similar authentication hiccups with .NET Core APIs on AWS Elastic Beanstalk before. Here's what's likely going wrong and how to fix it step by step:
1. 路由冲突导致的404错误
You've got both [Route] and [HttpGet] defining the same path on your API method, which creates duplicate route definitions. When you add [Authorize], the framework can't match the request properly and returns a 404. Also, it looks like your API controller is missing a base route prefix, which makes it even harder for requests to find their way to the controller.
Fix steps:
- Add a base route to your API controller class (and use
[ApiController]— it's a .NET Core 2.1+ feature that simplifies API behavior):[Route("api/[controller]")] [ApiController] public class YourApiController : ControllerBase { // Your methods go here } - Clean up the route on your method— keep only the
[HttpGet]definition:
Now your full API route will be[HttpGet("GetProjectTweets/{id}")] public async Task<List<InsytModels.Tweet>> GetProjectTweetsAsync(int id) { // Your existing code }api/YourControllerName/GetProjectTweets/{id}, which eliminates the routing conflict.
2. 认证中间件顺序错误(核心问题)
Middleware order in .NET Core make-or-break for authentication. Right now, you're running UseSignalR and UseMvc before UseAuthentication— that means requests hit your API controller before the authentication middleware has a chance to populate HttpContext.User, so curUser will always be null.
Fix steps:
Move app.UseAuthentication() to run before UseSignalR and UseMvc, right after UseSession:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseExceptionHandler("/Error"); app.UseHsts(); app.UseCors(MyAllowSpecificOrigins); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseSession(); // Move authentication middleware here app.UseAuthentication(); app.UseSignalR(routes => { routes.MapHub<TweetHub>("/tweetHub"); }); app.UseMvc(); }
Now every request to your API will go through authentication first, so HttpContext.User will have the logged-in user's info.
3. AJAX requests not sending authentication cookies
If you're calling the API from a frontend AJAX request (like fetch or axios), you need to explicitly tell the request to send authentication cookies. Razor pages automatically include cookies because they're server-rendered, but AJAX requests don't by default.
Fix steps:
- For axios requests, add
withCredentials: true:axios.get('/api/YourController/GetProjectTweets/1', { withCredentials: true }) - For fetch requests, add
credentials: 'include':fetch('/api/YourController/GetProjectTweets/1', { credentials: 'include' }) - Update your CORS policy too—
AllowAnyOrigindoesn't play nice withAllowCredentials. Replace it with your actual frontend domain:options.AddPolicy(MyAllowSpecificOrigins, builder => { builder.WithOrigins("https://your-frontend-domain.com") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); });
4. AWS Elastic Beanstalk反向代理配置问题
AWS EB uses a load balancer as a reverse proxy, and if you don't configure forwarded headers correctly, ASP.NET Core can't detect the real request protocol (HTTP/HTTPS) or client IP. This breaks cookie authentication because the Secure cookie attribute won't match the actual request.
Fix steps:
Update your ForwardedHeadersOptions to trust EB's proxy and forward the necessary headers:
services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // Trust all proxies (safe only in EB's managed environment) options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("0.0.0.0"), 0)); });
Then add app.UseForwardedHeaders() at the very start of your Configure method:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseForwardedHeaders(); // Add this first app.UseExceptionHandler("/Error"); // Rest of your middleware }
Final Check
After making these changes, add the [Authorize] attribute back to your API method and test it out:
[Authorize] [HttpGet("GetProjectTweets/{id}")] public async Task<List<InsytModels.Tweet>> GetProjectTweetsAsync(int id) { var curUser = await GetCurrentUserAsync(); // curUser should now be populated with the logged-in user var Project = await new Project().GetAsync(_context, id, curUser.Id); // Rest of your code }
内容的提问来源于stack exchange,提问作者Frankofoedu

