Should fail
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace OpenID_API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries =
|
||||
[
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
];
|
||||
|
||||
// Any authenticated user can access this endpoint, regardless of their role.
|
||||
// This is the most basic level of authorization, which only checks if the user is authenticated.
|
||||
[Authorize]
|
||||
// The following lines are examples of how to restrict access to specific roles. Uncomment the desired line(s) to apply the restriction.
|
||||
// This is the way you can specify multiple roles for an endpoint. You can use a comma-separated list to allow access to users with any of the specified roles.
|
||||
// [Authorize(Roles = "user")] //Only users with the "user" role can access this endpoint
|
||||
// [Authorize(Roles = "owner")] //Only users with the "owner" role can access this endpoint
|
||||
// [Authorize(Roles = "admin")] //Only users with the "admin" role can access this endpoint
|
||||
// [Authorize(Roles = "user,owner")] //Only users with either the "user" or "owner" role can access this endpoint
|
||||
[HttpGet]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
var xxx = User;
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
30
CommitHookTest/OpenID-API/Dockerfile
Normal file
30
CommitHookTest/OpenID-API/Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
||||
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
# This stage is used when running from VS in fast mode (Default for Debug configuration)
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||
USER $APP_UID
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
|
||||
# This stage is used to build the service project
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
COPY ["OpenID_API/OpenID_API.csproj", "OpenID_API/"]
|
||||
RUN dotnet restore "./OpenID_API/OpenID_API.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/OpenID_API"
|
||||
RUN dotnet build "./OpenID_API.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
# This stage is used to publish the service project to be copied to the final stage
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "./OpenID_API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "OpenID_API.dll"]
|
||||
19
CommitHookTest/OpenID-API/OpenID-API.csproj
Normal file
19
CommitHookTest/OpenID-API/OpenID-API.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>2d959f13-fec1-48ad-a7f1-455a8d4830d3</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.11" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.22.0" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="2.12.2" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
6
CommitHookTest/OpenID-API/OpenID-API.http
Normal file
6
CommitHookTest/OpenID-API/OpenID-API.http
Normal file
@@ -0,0 +1,6 @@
|
||||
@OpenID_API_HostAddress = http://localhost:5007
|
||||
|
||||
GET {{OpenID_API_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
||||
225
CommitHookTest/OpenID-API/OpenIDConnect/OpenIDConnectUtils.cs
Normal file
225
CommitHookTest/OpenID-API/OpenIDConnect/OpenIDConnectUtils.cs
Normal file
@@ -0,0 +1,225 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OpenApi;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Text;
|
||||
|
||||
|
||||
// Required NuGet Packages
|
||||
// Microsoft.AspNet.WebApi.Core
|
||||
// Microsoft.AspNetCore.Authentication.JwtBearer
|
||||
// Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||
// Microsoft.IdentityModel.Protocols.OpenIdConnect
|
||||
|
||||
|
||||
namespace OpenID_API.OpenIDConnect
|
||||
{
|
||||
public class OpenIDConnectUtils
|
||||
{
|
||||
// Configuration priority from highest to lowest
|
||||
// Highest: Command line arguments
|
||||
// : Non-prefixed environment variables
|
||||
// : User secrets from the .NET User Secrets Manager
|
||||
// : Any appsettings.{ ENVIRONMENT_NAME }.json files
|
||||
// : The appsettings.json file
|
||||
// Lowest : Fallback to the host configuration
|
||||
|
||||
/// <summary>
|
||||
/// Setting up OpenIDConnect authentication (Program.cs)
|
||||
/// </summary>
|
||||
/// <param name="builder">WebApplicationBuilder</param>
|
||||
|
||||
public void ConfigureBuilder(WebApplicationBuilder builder)
|
||||
{
|
||||
// Add services to the container.
|
||||
MyConfiguration.Set(builder.Configuration);
|
||||
|
||||
// >>> This adds the authentication service
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddCookie()
|
||||
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
|
||||
{
|
||||
options.Authority = builder.Configuration["OpenIDRealmURI"];
|
||||
options.Audience = builder.Configuration["OpenIDClient"];
|
||||
//options.TokenValidationParameters.RoleClaimType = "roles"; // adjust if your roles claim is named differently
|
||||
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
RoleClaimType = "roles", // 👈 IMPORTANT
|
||||
NameClaimType = "name",
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true
|
||||
};
|
||||
|
||||
options.MapInboundClaims = false; // prevent automatic claim type mapping
|
||||
options.RequireHttpsMetadata = true; // set to false only for development
|
||||
options.IncludeErrorDetails = true;
|
||||
|
||||
// Map claim types if needed
|
||||
//options.TokenValidationParameters = new TokenValidationParameters
|
||||
//{
|
||||
// NameClaimType = "name",
|
||||
// RoleClaimType = "roles"
|
||||
//};
|
||||
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnMessageReceived = context =>
|
||||
{
|
||||
// Optional: log the token or handle custom token retrieval
|
||||
var token = context.Request.Headers["Authorization"].ToString();
|
||||
string path = context.Request.Path;
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
Console.WriteLine("Access token");
|
||||
Console.WriteLine($"URL: {path}");
|
||||
Console.WriteLine($"Token: {token}\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Access token");
|
||||
Console.WriteLine("URL: " + path);
|
||||
Console.WriteLine("Token: No access token provided\r\n");
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
var loggerFactory = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>();
|
||||
var logger = loggerFactory.CreateLogger("Api.Authorization");
|
||||
var claims = context?.Principal?.Claims;
|
||||
if (claims is null || !claims.Any())
|
||||
{
|
||||
logger.LogWarning("Claims null or empty");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
var claimsBuilder = new StringBuilder();
|
||||
claimsBuilder.AppendLine("User Claims:");
|
||||
foreach (var claim in claims)
|
||||
{
|
||||
claimsBuilder.AppendLine($"[{claim.Type}] - [{claim.Value}]");
|
||||
}
|
||||
logger.LogTrace("{Claims}", claimsBuilder.ToString());
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
// Optional: log authentication failures
|
||||
Console.WriteLine("Authentication failed: " + context.Exception.Message);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
// <<< End of authentication service setup
|
||||
|
||||
// >>> This adds the authorization policies
|
||||
builder.Services
|
||||
.AddAuthorizationBuilder()
|
||||
.AddPolicy("read_access", builder =>
|
||||
{
|
||||
// claim, list of acceptable values
|
||||
builder.RequireClaim("myClaim", "MyClaimValueRO1", "MyClaimValueRO2");
|
||||
})
|
||||
.AddPolicy("write_access", builder =>
|
||||
{
|
||||
builder.RequireClaim("myClaim", "MyClaimValueRW1", "MyClaimValueRW2");
|
||||
})
|
||||
.AddPolicy("Admin", policy => policy.RequireClaim("roles", "admin", "warlock"));
|
||||
// <<< End of authorization policies setup
|
||||
|
||||
ConfigureBuilderOpenAPI(builder);
|
||||
|
||||
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
options.KnownIPNetworks.Clear();
|
||||
options.KnownProxies.Clear();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void ConfigureBuilderOpenAPI(WebApplicationBuilder builder)
|
||||
{
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
|
||||
// Add Swagger with Authorization option
|
||||
// https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/HEAD/docs/configure-and-customize-swaggergen.md#add-security-definitions-and-requirements
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc("v1", new OpenApiInfo
|
||||
{
|
||||
Title = "My API",
|
||||
Version = "v1"
|
||||
});
|
||||
options.AddSecurityDefinition("bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "bearer",
|
||||
BearerFormat = "JWT",
|
||||
Description = "JWT Authorization header using the Bearer scheme."
|
||||
});
|
||||
options.AddSecurityRequirement(document => new OpenApiSecurityRequirement
|
||||
{
|
||||
[new OpenApiSecuritySchemeReference("bearer", document)] = []
|
||||
});
|
||||
});
|
||||
// Add Swagger with Authorization option
|
||||
}
|
||||
|
||||
private void ConfigureAppOpenAPI(WebApplication app)
|
||||
{
|
||||
app.MapSwagger();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(options =>
|
||||
{
|
||||
options.SwaggerEndpoint("v1/swagger.json", "Your Name Here");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="app">WebApplication</param>
|
||||
public void ConfigureApp(WebApplication app)
|
||||
{
|
||||
if (app.Environment.IsDevelopment()) ConfigureAppOpenAPI(app);
|
||||
}
|
||||
|
||||
public JwtSecurityToken GetJwtPayload(HttpContext myContext)
|
||||
{
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
return handler.ReadJwtToken(myContext.GetTokenAsync("access_token").Result);
|
||||
}
|
||||
|
||||
public string GetJwtClaim(HttpContext myContext, string theClaim)
|
||||
{
|
||||
JwtSecurityToken jwtPayload = GetJwtPayload(myContext);
|
||||
return jwtPayload.Claims.FirstOrDefault(claim => claim.Type == theClaim).Value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static public class MyConfiguration
|
||||
{
|
||||
static ConfigurationManager _config;
|
||||
static public void Set(ConfigurationManager config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
static public ConfigurationManager Get()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
CommitHookTest/OpenID-API/Program.cs
Normal file
25
CommitHookTest/OpenID-API/Program.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using OpenID_API.OpenIDConnect;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Configure for OpenID
|
||||
OpenIDConnectUtils oidcConfig = new();
|
||||
oidcConfig.ConfigureBuilder(builder);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure for OpenID
|
||||
oidcConfig.ConfigureApp(app);
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
35
CommitHookTest/OpenID-API/Properties/launchSettings.json
Normal file
35
CommitHookTest/OpenID-API/Properties/launchSettings.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:8887"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:8888"
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker",
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_HTTPS_PORTS": "8081",
|
||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||
},
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
},
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json"
|
||||
}
|
||||
13
CommitHookTest/OpenID-API/WeatherForecast.cs
Normal file
13
CommitHookTest/OpenID-API/WeatherForecast.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace OpenID_API
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
8
CommitHookTest/OpenID-API/appsettings.Development.json
Normal file
8
CommitHookTest/OpenID-API/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
CommitHookTest/OpenID-API/appsettings.json
Normal file
16
CommitHookTest/OpenID-API/appsettings.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Microsoft.AspNetCore.Authentication": "Information",
|
||||
"Microsoft.AspNetCore.Authorization": "Information",
|
||||
"Api.Authorization": "Trace"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Comment1": "Configuration for OpenID Connect authentication",
|
||||
"OpenIDRealmURI": "https://auth.a.ucnit.eu/realms/xOIDCx",
|
||||
"OpenIDClient": "Alice",
|
||||
"OpenIDSecret": "JvDnso8O773pE9ENJdRhsrJd5pVD5Q86"
|
||||
}
|
||||
Reference in New Issue
Block a user