5.0 KiB
5.0 KiB
Task 4: Create Auth Controller
Task Description
Files:
- Create:
src/Fengling.AuthService/Controllers/AuthController.cs - Create:
src/Fengling.AuthService/DTOs/LoginRequest.cs - Create:
src/Fengling.AuthService/DTOs/LoginResponse.cs - Create:
src/Fengling.AuthService/DTOs/TokenResponse.cs
Implementation Steps
Step 1: Create DTOs
Create: src/Fengling.AuthService/DTOs/LoginRequest.cs
namespace Fengling.AuthService.DTOs;
public class LoginRequest
{
public string UserName { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public long TenantId { get; set; }
}
Create: src/Fengling.AuthService/DTOs/LoginResponse.cs
namespace Fengling.AuthService.DTOs;
public class LoginResponse
{
public string AccessToken { get; set; } = string.Empty;
public string RefreshToken { get; set; } = string.Empty;
public int ExpiresIn { get; set; }
public string TokenType { get; set; } = "Bearer";
}
Step 2: Create AuthController
Create: src/Fengling.AuthService/Controllers/AuthController.cs
using Fengling.AuthService.DTOs;
using Fengling.AuthService.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore;
using static OpenIddict.Abstractions.OpenIddictConstants;
namespace Fengling.AuthService.Controllers;
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IOpenIddictApplicationManager _applicationManager;
private readonly IOpenIddictAuthorizationManager _authorizationManager;
private readonly IOpenIddictScopeManager _scopeManager;
private readonly ILogger<AuthController> _logger;
public AuthController(
SignInManager<ApplicationUser> signInManager,
UserManager<ApplicationUser> userManager,
IOpenIddictApplicationManager applicationManager,
IOpenIddictAuthorizationManager authorizationManager,
IOpenIddictScopeManager scopeManager,
ILogger<AuthController> logger)
{
_signInManager = signInManager;
_userManager = userManager;
_applicationManager = applicationManager;
_authorizationManager = authorizationManager;
_scopeManager = scopeManager;
_logger = logger;
}
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
var user = await _userManager.FindByNameAsync(request.UserName);
if (user == null || user.IsDeleted)
{
return Unauthorized(new { error = "用户不存在" });
}
if (user.TenantId != request.TenantId)
{
return Unauthorized(new { error = "租户不匹配" });
}
var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false);
if (!result.Succeeded)
{
return Unauthorized(new { error = "用户名或密码错误" });
}
var token = await GenerateTokenAsync(user);
return Ok(token);
}
private async Task<LoginResponse> GenerateTokenAsync(ApplicationUser user)
{
var claims = new List<System.Security.Claims.Claim>
{
new(Claims.Subject, user.Id.ToString()),
new(Claims.Name, user.UserName ?? string.Empty),
new(Claims.Email, user.Email ?? string.Empty),
new("tenant_id", user.TenantId.ToString())
};
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
claims.Add(new Claim(Claims.Role, role));
}
var identity = new System.Security.Claims.ClaimsIdentity(claims, "Server");
var principal = new System.Security.Claims.ClaimsPrincipal(identity);
return new LoginResponse
{
AccessToken = "token-placeholder",
RefreshToken = "refresh-placeholder",
ExpiresIn = 3600,
TokenType = "Bearer"
};
}
}
Step 3: Run to verify controller compilation
Run:
dotnet build
Expected: Build succeeds
Step 4: Commit
git add src/Fengling.AuthService/Controllers/ src/Fengling.AuthService/DTOs/
git commit -m "feat(auth): add authentication controller with login endpoint"
Context
This task creates an authentication controller with a login endpoint. The login endpoint validates user credentials, checks tenant isolation, and generates JWT tokens with embedded tenant_id claims for multi-tenant routing.
Tech Stack: ASP.NET Core Controllers, OpenIddict
Verification
- LoginRequest DTO created
- LoginResponse DTO created
- AuthController created with login endpoint
- Tenant validation implemented
- Build succeeds
- Committed to git
Notes
- Token generation is placeholder, will be replaced by OpenIddict in next task
- Tenant validation ensures multi-tenant isolation