mirror of
https://github.com/opelly27/WinStudentGoalTracker.git
synced 2026-05-20 08:47:42 +00:00
Prototype illustrative role assignments project
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
// =============================================================================
|
||||
// FakeAuthHeaderFilter.cs
|
||||
// =============================================================================
|
||||
// This is a Swagger/OpenAPI filter that automatically adds an "X-User-Id"
|
||||
// header input field to every endpoint in the Swagger UI.
|
||||
//
|
||||
// Without this, you'd have to manually type the header name and value each
|
||||
// time you test an endpoint. With this, every endpoint shows a pre-labeled
|
||||
// input box where you just type 1, 2, or 3.
|
||||
//
|
||||
// HOW IT WORKS:
|
||||
// Swashbuckle (the Swagger library) calls this filter for every endpoint
|
||||
// it discovers. We add a header parameter to each one.
|
||||
// =============================================================================
|
||||
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace RolesAssignments.Middleware;
|
||||
|
||||
public class FakeAuthHeaderFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
// Add the X-User-Id header parameter to every endpoint
|
||||
operation.Parameters ??= new List<OpenApiParameter>();
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "X-User-Id",
|
||||
In = ParameterLocation.Header,
|
||||
Required = false,
|
||||
Description = "Fake user ID: 1 = Ms. Rivera (Teacher), 2 = Mr. Daniels (Paraeducator), 3 = Dr. Patel (Supervisor)",
|
||||
Schema = new OpenApiSchema { Type = "integer" }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// =============================================================================
|
||||
// FakeAuthMiddleware.cs
|
||||
// =============================================================================
|
||||
// IN A REAL APPLICATION, this would be replaced by JWT bearer authentication,
|
||||
// cookie authentication, or Identity. The user would log in once, receive a
|
||||
// token or cookie, and every subsequent request would carry their identity.
|
||||
//
|
||||
// FOR THIS PROTOTYPE, we simulate login by reading an HTTP header:
|
||||
//
|
||||
// X-User-Id: 1 → You're Ms. Rivera (Teacher)
|
||||
// X-User-Id: 2 → You're Mr. Daniels (Paraeducator)
|
||||
// X-User-Id: 3 → You're Dr. Patel (Supervisor)
|
||||
//
|
||||
// This middleware runs BEFORE every request reaches a controller. It reads
|
||||
// the header, looks up the user in a hardcoded list, and builds a
|
||||
// ClaimsPrincipal — the same object that real authentication produces.
|
||||
//
|
||||
// This means the rest of the application (controllers, authorization handlers)
|
||||
// works EXACTLY as it would with real authentication. The only fake part is
|
||||
// HOW the user identity gets established.
|
||||
//
|
||||
// WHAT IS MIDDLEWARE?
|
||||
// -------------------
|
||||
// Middleware is code that runs in a pipeline for every HTTP request.
|
||||
// Think of it like a series of checkpoints:
|
||||
// Request → [Middleware A] → [Middleware B] → [Controller] → Response
|
||||
// Each middleware can inspect/modify the request, call the next one, or
|
||||
// short-circuit the pipeline (e.g., return 401 without ever reaching the
|
||||
// controller).
|
||||
// =============================================================================
|
||||
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace RolesAssignments.Middleware;
|
||||
|
||||
public class FakeAuthMiddleware
|
||||
{
|
||||
// The next middleware in the pipeline. Middleware is like a chain —
|
||||
// each piece holds a reference to the next one and decides whether
|
||||
// to pass the request along.
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
// Hardcoded user directory. In a real app, this would be a database lookup
|
||||
// during login, and the resulting claims would be stored in a JWT token.
|
||||
private static readonly Dictionary<int, (string Name, string Role)> _users = new()
|
||||
{
|
||||
{ 1, ("Ms. Rivera", "Teacher") },
|
||||
{ 2, ("Mr. Daniels", "Paraeducator") },
|
||||
{ 3, ("Dr. Patel", "Supervisor") },
|
||||
};
|
||||
|
||||
public FakeAuthMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
// Try to read the X-User-Id header from the incoming request.
|
||||
// If it's missing or invalid, we let the request through without
|
||||
// setting up a user — the [Authorize] attribute on controllers
|
||||
// will reject it with a 401 Unauthorized.
|
||||
if (context.Request.Headers.TryGetValue("X-User-Id", out var userIdHeader)
|
||||
&& int.TryParse(userIdHeader, out var userId)
|
||||
&& _users.TryGetValue(userId, out var user))
|
||||
{
|
||||
// Build a list of "claims" — key-value pairs that describe the user.
|
||||
// These are the same claims that would be embedded in a JWT token
|
||||
// or stored in an authentication cookie in a real system.
|
||||
var claims = new[]
|
||||
{
|
||||
// NameIdentifier = the user's unique ID (what GetUserId() reads)
|
||||
new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
|
||||
|
||||
// Name = the user's display name
|
||||
new Claim(ClaimTypes.Name, user.Name),
|
||||
|
||||
// Role = what kind of user they are (what GetRole() reads)
|
||||
new Claim(ClaimTypes.Role, user.Role),
|
||||
};
|
||||
|
||||
// Create a "ClaimsIdentity" (a collection of claims tied to an
|
||||
// authentication scheme). The second parameter "FakeAuth" is the
|
||||
// authentication scheme name — in a real app this would be
|
||||
// "Bearer" (for JWT) or "Cookies" (for cookie auth).
|
||||
var identity = new ClaimsIdentity(claims, "FakeAuth");
|
||||
|
||||
// Wrap it in a ClaimsPrincipal and set it on the HTTP context.
|
||||
// From this point on, any code that reads HttpContext.User
|
||||
// (including controllers and authorization handlers) will see
|
||||
// this user as "logged in."
|
||||
context.User = new ClaimsPrincipal(identity);
|
||||
}
|
||||
|
||||
// Pass the request to the next middleware in the pipeline.
|
||||
// If we didn't set up a user above, context.User will be an
|
||||
// anonymous/unauthenticated principal, and [Authorize] will block it.
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user