在我的ASP.net网站中,我需要检查登录用户是属于某个角色,还是在我的数据库“UserInstance”表中的字段设置为true。要做到这一点,我可以做到以下几点。
if(Roles.IsUserInRole("Global Admin")
|| uow.UserInstanceService.GetUserInstance(userId,InstanceId).Admin)
{
//Do something
}
然而,由于我将要使用此代码,所以很多权限取决于登录用户要么是“全局管理员”还是我的表的字段是真的我不想写出来不断。
我发现的一个解决方案是在“UserInstance”服务中创建一个方法,该方法检查“IsUserAdminOrGlobalAdmin”方法中的两个方法。
public class UserInstanceService
{
IRepository<UserInstance> userInstanceRepository;
public UserInstanceService(IRepository<UserInstance> userInstanceRepository)
{
this.userInstanceRepository = userInstanceRepository;
}
public UserInstance GetByUserIdAndInstanceId(Guid userId, int instanceId)
{
return userInstanceRepository.GetSingle(u => u.UserId == userId && u.InstanceId == instanceId);
}
public bool IsUserAdminOrGlobalAdmin(Guid userId,int instanceId)
{
bool valid = false;
if (System.Web.Security.Roles.IsUserInRole("Global Admin"))
valid = true;
if (GetByUserIdAndInstanceId(userId, instanceId).Admin)
valid = true;
return valid;
}
//Removed rest of methods for readability
}
由于这是商务逻辑,我把这个方法放在我的“UserInstanceService”类中,该类与包含实体上下文的存储库类进行交互。这个服务类驻留在一个单独的Model项目中,所以我不得不添加对System.Web.Security的引用,我不确定这样做是不是很好。我注意到的一件事是我不能为这个方法编写单元测试,因为它依赖于用户登录。
所以我的问题是,在服务中结合HttpContext特定功能(如登录用户角色)是否可以接受?
编辑 - 阅读完答案后,我更改了我的代码,以便调用Auth服务(在Web应用程序项目中),然后调用UserInstanceService,就像这样。
public class Auth: IAuthService {
public bool IsUserAdminOrGlobalAdmin(Guid userId,int instanceId) {
myEntities entityContext = new myEntities
//RepsitoryBase inherits my IRepository<TEntity> class
UserInstanceService uis = new UserInstanceService(new RepositoryBase<UserInstance>(entityContext));
bool valid = false
if(Roles.IsUserInRole("Global Admin"))
valid = true;
if(uis.GetByUserIdAndInstanceId(userId,instanceId).Admin)
valid = true;
return valid;
}
}
所以我可以在我的网页中这样说这个
if(Auth.IsUserAdminOrGlobalAdmin(userId,InstanceId)
{
//Do stuff
}
答案 0 :(得分:2)
原始答案是在假设UserAccess需要身份验证的情况下编写的,但似乎身份验证使用了UserAccess;简单地反转依赖关系,但其他所有东西都应该以相同的方式使用。
原始答案:
将特定于ASP.NET的代码放入与存储库分开的自己的服务中。然后,该服务(例如,Auth服务)可以被需要访问集中式身份验证/授权逻辑的任何组件(例如UserInstanceService)使用。
Consume the Auth as a dependency per IoC principles,希望使用一些DI来让生活更轻松。
如果Auth服务保持独立,它也可以通过模拟进行测试,例如测试使用是否经过身份验证时会发生什么,这完全避免了为User服务设置完整ASP.NET堆栈的需要。
此外,由于服务(接口)和组件(类)是分开的,因此实用的HTTP利用组件可以存在于与服务不同的项目中并在以后连接 - 这将避免将Web依赖性引入到Model项目中
例如,
// This is the Service Contract and can live in the Model
public class IAuthService {
void AssertCurrentUserIsAdminOrGlobalAdmin();
void AssertIsUserAdminOrGlobalAdmin(Guid userId,int instanceId);
}
// This is the Component, which provides the Service, and is part
// of the Web/HTTP-specific project. It is wired up via IoC/DI from
// the large context of the application.
public class Auth: IAuthService {
public void AssertCurrentUserIsAdminOrGlobalAdmin() {
// This one already knows the applicable HTTP/User Context
}
public void AssertIsUserAdminOrGlobalAdmin(Guid userId,int instanceId) {
// Do whatever
}
}
// This Component is part of the Model
public class UserInstanceService
{
// IoC dependencies
IRepository<UserInstance> userInstanceRepository;
IAuthService authService;
}
答案 1 :(得分:0)
您可以在线程上设置当前主体并使用它。我认为这也是ASP.Net为您所做的大部分工作。