پیاده سازی authorization به روش AOP به کمک کتابخانه های SNAP و StructureMap
نویسنده: کاوه شهبازی
تاریخ: ۱۳۹۲/۰۸/۰۱ ۱۷:۵۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
PM> Install-Package snap.structuremap
StructureMap (≥ 2.6.4.1) CommonServiceLocator.StructureMapAdapter (≥ 1.1.0.3) SNAP (≥ 1.8) fasterflect (≥ 2.1.2) Castle.Core (≥ 3.1.0) CommonServiceLocator (≥ 1.0)
تنظیمات SNAP
namespace Framework.UI.Asp
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
initSnap();
initStructureMap();
}
private static void initSnap()
{
SnapConfiguration.For<StructureMapAspectContainer>(c =>
{
// Tell Snap to intercept types under the "Framework.ServiceLayer..." namespace.
c.IncludeNamespace("Framework.ServiceLayer.*");
// Register a custom interceptor (a.k.a. an aspect).
c.Bind<Framework.ServiceLayer.Aspects.AuthorizationInterceptor>()
.To<Framework.ServiceLayer.Aspects.AuthorizationAttribute>();
});
}
void Application_EndRequest(object sender, EventArgs e)
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
private static void initStructureMap()
{
var thread = StructureMap.Pipeline.Lifecycles.GetLifecycle(InstanceScope.HttpSession);
ObjectFactory.Configure(x =>
{
x.For<IUserManager>().Use<EFUserManager>();
x.For<IAuthorizationManager>().LifecycleIs(thread)
.Use<EFAuthorizationManager>().Named("_AuthorizationManager");
x.For<Framework.DataLayer.IUnitOfWork>()
.Use<Framework.DataLayer.Context>();
x.SetAllProperties(y =>
{
y.OfType<IUserManager>();
y.OfType<Framework.DataLayer.IUnitOfWork>();
y.OfType<Framework.Common.Web.IPageHelpers>();
});
});
}
}
} namespace Framework.ServiceLayer.Aspects
{
public class AuthorizationInterceptor : MethodInterceptor
{
public override void InterceptMethod(IInvocation invocation, MethodBase method, Attribute attribute)
{
var AuthManager = StructureMap.ObjectFactory
.GetInstance<Framework.ServiceLayer.UserManager.IAuthorizationManager>();
var FullName = GetMethodFullName(method);
if (!AuthManager.IsActionAuthorized(FullName))
throw new Common.Exceptions.UnauthorizedAccessException("");
invocation.Proceed(); // the underlying method call
}
private static string GetMethodFullName(MethodBase method)
{
var TypeName = (((System.Reflection.MemberInfo)(method)).DeclaringType).FullName;
return TypeName + "." + method.Name;
}
}
public class AuthorizationAttribute : MethodInterceptAttribute
{ } namespace Snap
{
public abstract class MethodInterceptor : IAttributeInterceptor, IInterceptor, IHideBaseTypes
{
protected MethodInterceptor();
public int Order { get; set; }
public Type TargetAttribute { get; set; }
public virtual void AfterInvocation();
public virtual void BeforeInvocation();
public void Intercept(IInvocation invocation);
public abstract void InterceptMethod(IInvocation invocation, MethodBase method, Attribute attribute);
public bool ShouldIntercept(IInvocation invocation);
}
} یک نکته
private void Application_PreRequestHandlerExecute(object source, EventArgs e)
{
var page = HttpContext.Current.Handler as BasePage; // The Page handler
if (page == null)
return;
WireUpThePage(page);
WireUpAllUserControls(page);
var UsrCod = HttpContext.Current.Session["UsrCod"];
if (UsrCod != null)
{
var _AuthorizationManager = ObjectFactory
.GetNamedInstance<Framework.ServiceLayer.UserManager.IAuthorizationManager>("_AuthorizationManager");
((Framework.ServiceLayer.UserManager.EFAuthorizationManager)_AuthorizationManager)
.AuditUserId = UsrCod.ToString();
}
} namespace Framework.ServiceLayer.UserManager
{
public class EFUserManager : IUserManager
{
IUnitOfWork _uow;
IDbSet<User> _users;
public EFUserManager(IUnitOfWork uow)
{
_uow = uow;
_users = _uow.Set<User>();
}
[Framework.ServiceLayer.Aspects.Authorization]
public List<User> GetAll()
{
return _users.ToList<User>();
}
}
} namespace Framework.ServiceLayer.UserManager
{
public class EFAuthorizationManager : IAuthorizationManager
{
public String AuditUserId { get; set; }
IUnitOfWork _uow;
public EFAuthorizationManager(IUnitOfWork uow)
{
_uow = uow;
}
public bool IsActionAuthorized(string actionName)
{
var res = _uow.Set<User>()
.Any(u => u.Id == AuditUserId &&
u.AllowedActions.Any(a => a.Name == actionName));
return res;
}
public bool IsPageAuthorized(string pageURL)
{
//TODO: بررسی وجود دسترسی باید پیاده سازی شود
//فقط برای تست
return true;
}
}
} namespace Framework.DataModel
{
public class User : BaseEntity
{
public string UserName { get; set; }
public string Password { get; set; }
//...
[Display(Name = "عملیات مجاز")]
public virtual ICollection<Action> AllowedActions { get; set; }
}
public class Action:BaseEntity
{
public string Name { get; set; }
public Entity RelatedEntity { get; set; }
//...
public virtual ICollection<User> AllowedUsers { get; set; }
}
public abstract class BaseEntity
{
[Key]
public int Id { get; set; }
//...
}
}