wip: oauth

This commit is contained in:
2024-10-13 22:12:43 +07:00
parent e9f32fc32e
commit b7150c7c43
14 changed files with 234 additions and 65 deletions

View File

@@ -16,6 +16,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RsaKeyLoader", "RsaKeyLoade
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jwt.Application", "Jwt.Application\Jwt.Application.csproj", "{E1DC6422-489C-424C-BC3A-3844599B43C9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OAuth", "OAuth", "{DF15C7CD-6348-49E9-8FEB-ACA68F530044}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OAuth.Authentik", "OAuth.Authentik\OAuth.Authentik.csproj", "{1996966F-793B-4FFD-8664-E73690350FDE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -46,6 +50,10 @@ Global
{E1DC6422-489C-424C-BC3A-3844599B43C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1DC6422-489C-424C-BC3A-3844599B43C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1DC6422-489C-424C-BC3A-3844599B43C9}.Release|Any CPU.Build.0 = Release|Any CPU
{1996966F-793B-4FFD-8664-E73690350FDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1996966F-793B-4FFD-8664-E73690350FDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1996966F-793B-4FFD-8664-E73690350FDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1996966F-793B-4FFD-8664-E73690350FDE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{3684B6DC-9301-496C-9832-FFC26084C496} = {A7B682CD-CF61-4684-977B-82E48A4051D8}
@@ -53,5 +61,6 @@ Global
{BAD4810F-B60A-42F1-8176-649855B93794} = {29AFF1AF-FE18-491A-AFE1-CE2786187166}
{579C8783-7E95-40F3-96F4-BEBFB40F2D38} = {29AFF1AF-FE18-491A-AFE1-CE2786187166}
{E1DC6422-489C-424C-BC3A-3844599B43C9} = {29AFF1AF-FE18-491A-AFE1-CE2786187166}
{1996966F-793B-4FFD-8664-E73690350FDE} = {DF15C7CD-6348-49E9-8FEB-ACA68F530044}
EndGlobalSection
EndGlobal

View File

@@ -9,7 +9,7 @@ var builder = WebApplication.CreateBuilder(args);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDataProtection();
var app = builder.Build();
// Configure the HTTP request pipeline.
@@ -65,7 +65,7 @@ app.MapGet("/login-user", (HttpContext ctx) =>
#region Secured
//todo: add to services
//builder.Services.AddDataProtection();
const string DataProtectorName = "cookie-protector";
// https://learn.microsoft.com/ru-ru/dotnet/api/microsoft.aspnetcore.dataprotection.idataprotector?view=aspnetcore-8.0
@@ -113,37 +113,37 @@ app.MapGet("/secured-method-protected", (HttpContext ctx, [FromServices] IDataPr
//todo: uncomment
//
// app.Use((ctx,next) =>
// {
// var protector = ctx.RequestServices.GetService<IDataProtectionProvider>();
// var dp = protector.CreateProtector(DataProtectorName);
//
// // authentication
// if (ctx.Request.Cookies.ContainsKey(AuthCookie))
// {
// var cookie = ctx.Request.Cookies[AuthCookie]!;
//
// var cookieUnprotected = dp.Unprotect(cookie);
//
// var parts = cookieUnprotected.Split("&").ToList();
// var entityType = parts[1].Split(":")[1];
// var entityName = parts[0].Split(":")[1];
//
// // authorization
// var claims = new List<Claim>();
// claims.Add(new Claim("Type", entityType));
// claims.Add(new Claim("Name", entityName));
//
// var identity = new ClaimsIdentity(claims);
// var user = new ClaimsPrincipal(identity);
// ctx.User = user;
//
// return next();
// }
//
// ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
// return Task.CompletedTask;
// });
app.Use((ctx,next) =>
{
var protector = ctx.RequestServices.GetService<IDataProtectionProvider>();
var dp = protector.CreateProtector(DataProtectorName);
// authentication
if (ctx.Request.Cookies.ContainsKey(AuthCookie))
{
var cookie = ctx.Request.Cookies[AuthCookie]!;
var cookieUnprotected = dp.Unprotect(cookie);
var parts = cookieUnprotected.Split("&").ToList();
var entityType = parts[1].Split(":")[1];
var entityName = parts[0].Split(":")[1];
// authorization
var claims = new List<Claim>();
claims.Add(new Claim("Type", entityType));
claims.Add(new Claim("Name", entityName));
var identity = new ClaimsIdentity(claims);
var user = new ClaimsPrincipal(identity);
ctx.User = user;
return next();
}
ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
});
app.MapGet("/login-user-claims", (HttpContext ctx, [FromServices] IDataProtectionProvider protector) =>
{

View File

@@ -12,8 +12,7 @@
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5163",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -22,8 +21,7 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7254;http://localhost:5163",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"

View File

@@ -12,9 +12,10 @@ builder.Services.AddSwaggerGen();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/login";
//options.Events
//options.LoginPath = "/login";
});
// builder.Services.AddAuthorization();
builder.Services.AddAuthorization();
var app = builder.Build();
@@ -27,8 +28,9 @@ if (app.Environment.IsDevelopment())
app.UseHttpsRedirection();
app.UseAuthentication();
// app.UseAuthorization();
app.MapGet("/secured-method", /*[Authorize]*/ (HttpContext ctx) =>
app.UseAuthorization();
app.MapGet("/secured-method", [Authorize] (HttpContext ctx) =>
{
var user = ctx.User?.FindFirst("Name");
if (user == null)

View File

@@ -12,8 +12,6 @@
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5209",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -22,8 +20,6 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7089;http://localhost:5209",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"

View File

@@ -12,8 +12,7 @@
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:7001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -22,8 +21,7 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7000;http://localhost:7001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"

View File

@@ -41,18 +41,18 @@ builder.Services.AddAuthentication()
}
};
// b.Events = new JwtBearerEvents()
// {
// OnMessageReceived = (ctx) =>
// {
// if (ctx.Request.Query.ContainsKey("token"))
// {
// ctx.Token = ctx.Request.Query["token"];
// }
//
// return Task.CompletedTask;
// }
// };
b.Events = new JwtBearerEvents()
{
OnMessageReceived = (ctx) =>
{
if (ctx.Request.Query.ContainsKey("token"))
{
ctx.Token = ctx.Request.Query["token"];
}
return Task.CompletedTask;
}
};
});
builder.Services.AddAuthorization();

View File

@@ -12,8 +12,7 @@
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
@@ -22,8 +21,7 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5000;http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.6"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
@OAuth.Authentik_HostAddress = http://localhost:5127
GET {{OAuth.Authentik_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@@ -0,0 +1,90 @@
using Microsoft.AspNetCore.Authentication.Cookies;
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.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://oauth.e1lama.ru/application/o/asp_net";
options.ClientId = "";
// Securely store and load this value
options.ClientSecret = "";
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
NameClaimType = "name"
};
// Optionally handle events
options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents
{
OnAuthenticationFailed = context =>
{
// Log or handle authentication failures
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
// Additional token validation can go here
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("/me", (HttpContext ctx) =>
{
return ctx.User.Claims.Select(x => (x.Type, x.Value));
})
.RequireAuthorization()
.WithOpenApi();
app.MapGet("/login", () =>
{
return Results.Challenge(authenticationSchemes: new List<string>(){"oidc"});
});
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

View File

@@ -0,0 +1,39 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:46291",
"sslPort": 44372
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:5000;http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}