diff --git a/OAuthServer/Controllers/LoginController.cs b/OAuthServer/Controllers/LoginController.cs index 3189cce..2ec1c9d 100644 --- a/OAuthServer/Controllers/LoginController.cs +++ b/OAuthServer/Controllers/LoginController.cs @@ -79,7 +79,7 @@ public class LoginController : ControllerBase if (result.Succeeded) { - return Redirect(returnUrl ?? ""); + return Redirect(returnUrl ?? "/"); } if (result.IsLockedOut) diff --git a/OAuthServer/OAuthServer.csproj b/OAuthServer/OAuthServer.csproj index c62d031..312fb96 100644 --- a/OAuthServer/OAuthServer.csproj +++ b/OAuthServer/OAuthServer.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -6,19 +6,20 @@ enable true Linux - + 01456bf0-f709-42b0-ad41-af6d7b94cab7 + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/OAuthServer/Program.cs b/OAuthServer/Program.cs index a8dffab..9653dbd 100644 --- a/OAuthServer/Program.cs +++ b/OAuthServer/Program.cs @@ -1,9 +1,10 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; +using System.Security.Cryptography; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption; using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using OAuthServer; @@ -31,6 +32,20 @@ builder.Services.AddSwaggerGen(options => Id = "Bearer" } }); + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer" + } + }, + new string[] { } + } + }); }); builder.Services.AddDbContext(options => { options.UseSqlite("DataSource=db.sqlite3"); }); @@ -39,24 +54,40 @@ builder.Services.AddIdentity(options => { options.St .AddEntityFrameworkStores() .AddDefaultTokenProviders(); +// Load the signing key from a file if it exists or create a new one +var rsaKey = RSA.Create(); +const string jwtKeyPath = ".aspnet/jwt-key"; +string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); +string fullPath = Path.Combine(home, jwtKeyPath); +if (File.Exists(fullPath)) +{ + rsaKey.ImportRSAPrivateKey(File.ReadAllBytes(fullPath), out _); +} +else +{ + string? dirName = Path.GetDirectoryName(fullPath); + if (!string.IsNullOrEmpty(dirName)) + Directory.CreateDirectory(dirName); + + var privateKey = rsaKey.ExportRSAPrivateKey(); + File.WriteAllBytes(fullPath, privateKey); +} + +// Add the JWT authentication method builder.Services.AddAuthentication().AddJwtBearer("OAuthToken", options => { - // options.RequireHttpsMetadata = false; - // options.SaveToken = true; - // options.TokenValidationParameters = new TokenValidationParameters() - // { - // ValidateIssuer = true, - // ValidateAudience = true, - // RequireSignedTokens = true, - // ValidIssuer = builder.Configuration["Jwt:Issuer"], - // ValidAudience = builder.Configuration["Jwt:Audience"], - // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Environment.GetEnvironmentVariable("JWT_KEY"))) - // }; + options.SaveToken = false; + options.TokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuer = false, + ValidateAudience = false, + RequireSignedTokens = true, + IssuerSigningKey = new RsaSecurityKey(rsaKey) + }; }); builder.Services.Configure(options => { - // SignIn settings. options.SignIn.RequireConfirmedAccount = false; options.SignIn.RequireConfirmedEmail = false; @@ -116,7 +147,7 @@ builder.Services.AddAuthorization(options => // Require the External role to authenticate with a different authentication method options.AddPolicy("External", policy => policy .RequireRole("External") - .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) + .AddAuthenticationSchemes("OAuthToken") ); });