В Program.cs у меня есть конечная точка сообщения для получения токена Jwt:
app.MapPost("/api/security/getToken", [AllowAnonymous] async (UserManager<IdentityUser> userMgr, UserLoginDTO user) => {
var identityUser = await userMgr.FindByEmailAsync(user.Email);
if (await userMgr.CheckPasswordAsync(identityUser, user.Password)) {
var issuer = builder.Configuration["Jwt:Issuer"];
var audience = builder.Configuration["Jwt:Audience"];
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim> {
new Claim(ClaimTypes.Email, identityUser.Email),
new Claim(ClaimTypes.GivenName, identityUser.UserName)
};;
var token = new JwtSecurityToken(issuer: issuer, audience: audience, signingCredentials: credentials, claims: claims);
var tokenHandler = new JwtSecurityTokenHandler();
var stringToken = tokenHandler.WriteToken(token);
return Results.Ok(stringToken);
}
else {
return Results.Unauthorized();
}
}).WithTags("Security");
Я хочу переместить эту логику в отдельный класс для удобства чтения.
public static class SecurityEndpoints {
public static void MapSecurityEndpoints(this WebApplication app) {
app.MapPost("/api/security/getToken", GetToken).AllowAnonymous();
app.MapPost("/api/security/createUser", CreateUser).AllowAnonymous();
}
internal static async Task<IResult> GetToken(this WebApplicationBuilder builder, UserManager<IdentityUser> userMgr,[FromBody] UserLoginDTO user) {
//same logic
}
...
}
Из-за WebApplicationBuilder я получаю InvalidOperationException.
Как реорганизовать метод GetToken, чтобы избавиться от WebApplicationBuilder и, возможно, получить доступ к деталям builder.Configuration, которые мне нужны для другой службы? Как будет выглядеть этот сервис? Или как еще вы бы подошли к этому?
Вы не должны использовать WebApplication(Builder)
в своих обработчиках. Используйте стандартные подходы для работы с конфигурацией в .NET/ASP.NET Core, которые описаны здесь.
Например, создайте тип для настроек jwt, зарегистрируйте его с помощью шаблона параметров и внедрите в обработчик. Что-то в этом роде:
public class JwtOptions
{
public const string Position = "Jwt";
public string Issuer { get; set; } = String.Empty;
public string Audience { get; set; } = String.Empty;
}
builder.Services.Configure<JwtOptions>(
builder.Configuration.GetSection(JwtOptions.Position));
internal static async Task<IResult> GetToken(IOptions<JwtOptions> jwtOptions,...) {
// use jwtOptions
}
Посмотрите на stackoverflow.com/questions/70139392/…