Jasinski Technical Wiki

Navigation

Home Page
Index
All Pages

Quick Search
»
Advanced Search »

Contributor Links

Create a new Page
Administration
File Management
Login/Logout
Your Profile

Other Wiki Sections

Software

PoweredBy

Page History: Data-Level Security - ASP.NET Core and EF Core

Compare Page Revisions



« Older Revision - Back to Page History - Newer Revision »


Page Revision: Fri, Aug 27, 2021, 10:15 AM


Overview

TODO

Reusable Code

Notes

  • _context and _db is a DatabaseContext
  • AuthMeta and AuthorizedMeta.Current refer to an object which contains info about the currently logged-in user.
  • UserTypeId is a general categorization of users, which may or may not be used in a particular system.

IUserCanAccess Interface

public interface IUserCanAccess
{
    bool UserCanAccessEntity(NetSoftDataModel db, int id, string userId, int? labId, UserTypeEnum userTypeId);
}

SecurityHelper Static Class

using Microsoft.AspNetCore.Http;
using System;

public static class SecurityHelper
{
    public  static int? GetLabId(HttpRequest request, bool allowNull = false)
    {
        /*--- If the user is assigned a lab, return that lab ---*/
        if (AuthorizedMeta.Current?.LabId != null)
        {
            return AuthorizedMeta.Current.LabId;
        }

        /*--- Otherwise, check the query string ---*/
        var labId = GetQueryStringItem(request, "labId");

        if (labId == null && !allowNull)
        {
            throw new Exception("Invalid Lab ID");
        }

        return labId;
    }
    private static int? GetQueryStringItem(HttpRequest request, string key)
    {
        var val = request.Query.ContainsKey(key) ?
            request.Query[key][0] :
            null;

        if (int.TryParse(val, out int result))
        {
            return result;
        }

        return null;
    }
}

ValidateUserCanAccessAttribute

using System;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ValidateUserCanAccessAttribute : Attribute
{
    public string IdRouteParameterName { get; private set; }
    public Type EntityType { get; private set; }
    public ValidateUserCanAccessAttribute(Type entityType, string idRouteParameterName)
    {
        EntityType = entityType;
        IdRouteParameterName = idRouteParameterName;
    }
}

ValidateUserCanAccess Controller Extension Method

protected void ValidateUserCanAccess<T>(int id)
    where T : IUserCanAccess, new()
{
    var a = new T();

    /* TODO: Replace "Tenant" with the name of your tenant table.    */
    /* If not a multi-tenant application, replace with string.Empty. */
    var labId = a.GetType().Name == "Tenant" ? 
        AuthorizedMeta.Current.LabId : 
        SecurityHelper.GetLabId(Request);

    if (!a.UserCanAccessEntity(_context, id, AuthMeta.UserId, labId, AuthorizedMeta.Current.UserTypeId))
    {
        throw new UnauthorizedAccessException($"User can't access {a.GetType().Name} {id}.");
    }
}



ScrewTurn Wiki version 3.0.1.400. Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.