using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Security.Cryptography; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Tokens; using RsaKeyLoader; var _users = new List<(string Name, string Id)>() { new ValueTuple("Danil", Guid.NewGuid().ToString()) }; var _rsaKey = KeyLoader.GetGeneratedKey(); var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // todo: package Microsoft.AspNetCore.Authentication.JwtBearer; builder.Services.AddAuthentication() .AddJwtBearer(b => { b.TokenValidationParameters = new TokenValidationParameters() { // для облегчения дебага ValidateAudience = false, ValidateIssuer = false, }; // important b.Configuration = new OpenIdConnectConfiguration() { SigningKeys = { new RsaSecurityKey(_rsaKey) } }; b.Events = new JwtBearerEvents() { OnMessageReceived = (ctx) => { if (ctx.Request.Query.ContainsKey("token")) { ctx.Token = ctx.Request.Query["token"]; } return Task.CompletedTask; } }; }); builder.Services.AddAuthorization(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); return forecast; }) .RequireAuthorization() .WithName("GetWeatherForecast") .WithOpenApi(); app.MapGet("/login", (string userName) => { var user = _users.First(x => x.Name == userName); var handler = new JwtSecurityTokenHandler(); var key = new RsaSecurityKey(_rsaKey); var token = handler.CreateToken(new SecurityTokenDescriptor() { Issuer = "https://localhost:5000", Subject = new ClaimsIdentity(new List() { new Claim("sub", user.Id), new Claim("name", user.Name) }), // important SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256) }); return handler.WriteToken(token); }); app.MapGet("/jwk", () => { var publicKey = RSA.Create(); publicKey.ImportRSAPublicKey(_rsaKey.ExportRSAPublicKey(), out _); var key = new RsaSecurityKey(publicKey); return JsonWebKeyConverter.ConvertFromRSASecurityKey(key); }); app.Run(); record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); } /* script: const token = ''; fetch("/weatherforecast", { method: "GET", headers: { "Accept": "application/json", "Authorization": "Bearer " + token } }).then(r => r.json()).then(r => console.log(r)); */