[Se]   En

Uppgraderat bloggskript till "Blog System 2.2"

  Annice      2020-11-28      Uppdateringar, C#, ASP.NET Core

Jag har nu uppgraderat C#-skriptet "Blog System 2.0" till version 2.2. Det nya skriptet "Blog System 2.2" finns nu också tillgängligt för nedladdning inne på skriptsidan.

Den ändring som gjorts är att säkerställa att ingen anonym besökare kan direktnavigera till ett inläggs-ID som skulle ha statusen "utkast", d.v.s. ett icke-publicerat blogginlägg.

Autentiseringen i detta skript hanteras huvudsakligen via en middleware som känner av namn på controllers som efterfrågas i varje HTTP-begäran av olika admin-sidor. Med andra ord säkerställer den s.k. auth-servern genom denna middleware att controllers som renderar olika adminsidor inte visar dessa sidor för obehöriga besökare. Nedanstående kodavsnitt som hanterar denna kontroll hittas i skriptfilen "AuthServer.cs" i mappen "Middleware":

public async Task InvokeAsync(HttpContext context, [FromServices] IAuthHandler handler)
{
  string[] paths = { "/Entry", "/Comment", "/Category", "/User" };

  foreach(string path in paths)
  {
    if (!handler.IsLoggedIn() && context.Request.Path.ToString().StartsWith(path))
    {
      context.Response.StatusCode = 401; // Unauthorized.
      context.Response.Redirect(context.Request.Scheme + "://" + context.Request.Host + "/Home/AccessDenied");
      return;
    }
  }

  await _next.Invoke(context);
}


För att säkerställa att dessa controllers dock alltid nås av en inloggad admin anropas samtidigt en s.k. auth-handler-tjänst. Auth-handler-tjänsten kontrollerar i nästa tur om en sessionsvariabel är satt som tillfälligt sparat en admins användar-ID vid en giltig inloggning. Kontrollmetoden som anropas via auth-servern ovan och som alltså kontrollerar om detta sessionsvärde existerar kan vidare hittas i skriptfilen "AuthHandler.cs" i mappen "Services":

public bool IsLoggedIn()
{
  var scope = _scope.CreateScope();
  var context = scope.ServiceProvider.GetService <IHttpContextAccessor>();

  // If user session is set, it means we have a valid login:
  if (context.HttpContext.Session.GetString("UserID") != null)
      return true;
  else
     return false;
}


Den controller som vidare hanterar de publika sidorna i detta bloggsystem heter i nästa tur "HomeController". Det är också den controllern som hanterar varje blogginläggs detaljsida, d.v.s. där man kan läsa ett inlägg i sin helhet samt där besökare kan lämna kommentarer. Då denna controller hanterar dessa detaljsidor oavsett om de är utkast eller publicerade - samt att controllernamnet "Home" inte kontrolleras av auth-servern - behövde alltså en check läggas till i denna controller för att säkerställa att endast adminanvändare kan navigera och se utkastsinlägg. Det gjordes vidare genom att lägga till ett villkor i action-metoden "EntryComments" som renderar detaljsidor enligt kodavsnittet nedan:

[HttpGet]
public IActionResult EntryComments(int? id)
{
  // Catch posted feedback:
  ViewBag.Success = TempData["Success"];
 
  // Check valid admin login if draft entry:
  if (HttpContext.Session.GetString("UserID") == null &&
      _db.BsEntries.Where(e =>e.Id == id && e.IsPublished == false).Any())
  {
    return RedirectToAction(nameof(Index));
  }

(...)


Villkoret i if-satsen ovan kontrollerar nu alltså om admin-sessionen är okänd samtidigt som inläggs-ID:t som efterfrågas är ett utkast. I detta fall kommer i så fall besökaren tolkas som anonym och bara skickas vidare till den publika startsidan, d.v.s. aldrig komma åt det efterfrågade inlägget. Den tillagda koden ovan hittas för övrigt i sin helhetskontext i skriptfilen "HomeController.cs" i mappen "Controllers".