| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- using System.Security.Claims;
- using Fido2NetLib;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.IdentityModel.Tokens;
- using Passwordless;
- // TODO: RoslynPad code for key generation
- var jwk = JsonWebKey.Create(File.ReadAllText("./demo-jwk.json"));
- //var host = "http://localhost:5172";
- var host = "https://demo.larcanum.net";
- 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();
- builder.Services.AddFido2(options =>
- {
- // server domain MUST match the actual domain name that the client uses to make the request from
- options.ServerDomain = host.Substring(host.LastIndexOf("/", StringComparison.Ordinal) + 1);
- options.ServerName = "FIDO2 Test";
- options.Origins = [host];
- options.TimestampDriftTolerance = 300000;
- });
- builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
- .AddJwtBearer(options =>
- {
- options.Events = new JwtBearerEvents()
- {
- OnAuthenticationFailed = ctx =>
- {
- Console.WriteLine(ctx.Exception);
- return Task.CompletedTask;
- },
- OnTokenValidated = ctx =>
- {
- Console.WriteLine($"Valid token from {ctx.SecurityToken.Issuer}");
- return Task.CompletedTask;
- }
- };
- options.RequireHttpsMetadata = false; // dev only!!!
- options.Authority = host;
- options.TokenValidationParameters = new TokenValidationParameters
- {
- IssuerSigningKey = jwk,
- ValidIssuer = host,
- ValidAudience = host,
- NameClaimType = ClaimTypes.NameIdentifier, // important to get the "sub" claim mapped to User.Identity.Name
- RoleClaimType = ClaimTypes.Role,
- };
- });
- builder.Services.AddAuthorization(authorizationOptions =>
- {
- authorizationOptions.AddPolicy("ProtectedPolicy", policyBuilder => policyBuilder
- .RequireClaim("permissions", "MagicClaim")
- .RequireRole("grunt"));
- });
- builder.Services.AddMemoryCache();
- builder.Services.Configure<JwtConfig>(config =>
- {
- config.Key = jwk;
- config.Host = host;
- });
- builder.Services.AddTransient<OptionsCache>();
- builder.Services.AddTransient<CredentialManager>();
- var app = builder.Build();
- // Configure the HTTP request pipeline.
- if (app.Environment.IsDevelopment())
- {
- app.UseSwagger();
- app.UseSwaggerUI();
- }
- app.UseStaticFiles();
- app.UseHttpsRedirection();
- app.UseAuthorization();
- app.MapGet("/buildCredentialOptions", ([FromQuery] string login, CredentialManager credMan) =>
- credMan.BuildCredentialOptions(login))
- .WithName("BuildCredentialOptions")
- .WithOpenApi();
- app.MapPost("/registerCredential", async ([FromQuery] string login, [FromBody] AuthenticatorAttestationRawResponse attestationResponse, CredentialManager credMan) =>
- await credMan.RegisterCredential(login, attestationResponse))
- .WithName("RegisterCredential")
- .WithOpenApi();
- app.MapGet("/buildAssertionOptions", async ([FromQuery] string login, CredentialManager credMan) =>
- await credMan.BuildAssertionOptions(login))
- .WithName("BuildAssertionOptions")
- .WithOpenApi();
- app.MapPost("/verifyCredential", async ([FromBody] AuthenticatorAssertionRawResponse assertionResponse, CredentialManager credMan) =>
- Results.Json(await credMan.VerifyCredential(assertionResponse)))
- .WithName("VerifyCredential")
- .WithOpenApi();
- app
- .MapGet("/protected", (HttpContext context) =>
- {
- var data = new Dictionary<string, object>
- {
- ["Status"] = "Success!",
- ["UserName"] = context.User?.Identity?.Name ?? "<unknown>",
- ["Permissions"] = context.User?.Claims.Where(c => c.Type == "permissions").Select(c => c.Value) ?? Enumerable.Empty<string>(),
- ["IsAdmin"] = context.User?.IsInRole("admin"),
- ["IsGrunt"] = context.User?.IsInRole("grunt"),
- ["IsNoob"] = context.User?.IsInRole("noob"),
- };
- return data;
- })
- .WithName("Protected")
- .RequireAuthorization("ProtectedPolicy");
- // .RequireAuthorization(policy =>
- // {
- // policy.RequireAuthenticatedUser();
- // });
- app.Run();
|