kreta/KretaWeb/Security/MvcResourceAuthorizeAttribute.cs
2024-03-13 00:33:46 +01:00

85 lines
2.9 KiB
C#

using System;
using System.Security.Claims;
using System.Web;
using System.Web.Mvc;
using AuthorizationContext = System.Web.Mvc.AuthorizationContext;
namespace Kreta.Web.Security
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class MvcResourceAuthorizeAttribute : AuthorizeAttribute
{
private string resource;
private string action;
private string[] additionalResources;
public MvcResourceAuthorizeAttribute()
{
}
public MvcResourceAuthorizeAttribute(string action, string resource, params string[] additionalResources)
{
this.action = action;
this.resource = resource;
this.additionalResources = additionalResources;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (AuthorizeCore(filterContext.HttpContext))
{
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
cache.SetProxyMaxAge(new TimeSpan(0L));
cache.AddValidationCallback(new HttpCacheValidateHandler(CacheValidateHandler), null);
}
else
{
HandleUnauthorizedRequest(filterContext);
}
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return CheckAccess(action, resource, additionalResources);
}
public bool IsAuthorized(HttpContextBase httpContext)
{
return AuthorizeCore(httpContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new HttpUnauthorizedResult();
}
protected override HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
{
return !AuthorizeCore(httpContext) ? HttpValidationStatus.IgnoreThisRequest : HttpValidationStatus.Valid;
}
private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
private static bool CheckAccess(string claimType, string resource, params string[] additionalResources)
{
var principal = HttpContext.Current.User as ClaimsPrincipal;
return CheckAccess(
principal,
claimType,
resource,
additionalResources);
}
private static bool CheckAccess(ClaimsPrincipal principal, string claimType, string resource, params string[] additionalResources)
{
bool access = resource == null ? principal.ClaimExists(claimType) : principal.ClaimExists(claimType, new[] { resource });
return access;
}
}
}