.Net core 根据登录用户的角色从数据库查询数据

问题描述

NET 3.1 核心项目。我已经在 azure AD 中注册了应用程序,并且已经进行了配置以接收 JWT 令牌中的角色。我有全局管理员、区域管理员用户等角色。目前在 .Net 核心中,我有 APIS,APIS 将发送和接收来自数据库的数据。大部分 APIS 将由以下所有角色访问。

[Authorize(Roles = "GlobalAdmin,RegionAdmin,User")]

现在来到 DAL 或数据的后面部分,我需要根据角色检索数据。例如,

如果角色是 GlobalAdmin 则返回所有数据 如果角色是区域管理员,则返回区域特定数据 如果角色是用户,则只返回他的数据。

我在 DAL 层有以下实现

  var returnData = await _mysamplerepository.GetAsync(x => x.id == request.rId,null,x => 
  x.ReferenceSystem).ConfigureAwait(false);

这是 RBAC 之前的一些示例查询。现在我想根据用户角色返回数据。我在想这样的事情

if(role == "GlobalAdmin")
Then return all the data(Similar to select * from)
if(role == "RegionAdmin")
Then return data for that region(similar to select * from table name where region = some region)
if(role == "user")
Then return only his data(similar to select * from table where createdby = 'currentuser')

以上是用来解释我脑子里的逻辑的虚拟代码。我想知道这是处理这种情况的正确方法或任何其他正式方法

现在我想到的另一个问题是在 JWT 令牌中我有角色。当我申请

[Authorize(Roles = "GlobalAdmin,User")]

.Net 会自动从令牌中读取角色并进行授权。现在,如果我想将角色详细信息传递给 DAL,我需要读取角色并将其传递给 DAL。所以我只是想知道我们如何从 JWT 令牌中读取语法上的角色并将其传递给 DAL 层以根据角色应用一些业务逻辑。

有人可以帮我解决这个问题吗?任何帮助,将不胜感激。谢谢

解决方法

您可以在方法中使用 User.IsInRole("roleName"),请参阅 here

if(User.IsInRole("GlobalAdmin")) {
    // Then return all the data(Similar to select * from)
}
if(User.IsInRole("RegionAdmin")) {
    // Then return data for that region(similar to select * from table name where region = some region)
}
if(User.IsInRole("user")) {
    // Then return only his data(similar to select * from table where createdby = 'currentuser')
}

如果您提到的角色是 azure 广告中的应用角色,您可以调用 Microsoft Graph API

string graphRequest = $"https://graph.microsoft.com/v1.0/users/{user-object-id}/appRoleAssignments";
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get,graphRequest);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer",authResult.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);

更新:

门户中的用户对象 ID:

enter image description here

或者您可以使用 API 列出用户,id 将显示对象 ID。

https://graph.microsoft.com/v1.0/users?$filter=startswith(displayName,'xxxx')

OP 的解决方案:我可以从声明中获取角色以及如下所示。

User.Identities.SelectMany(s => s.Claims).Where(s => s.Type.Contains("role")).Select(s => s.Value);

似乎是指这里:https://stackoverflow.com/a/21690079/13308381

,

我们有一个情况非常相似的商业应用。将“用户”、“组管理员”和“管理员”作为角色。

在您的场景中,您可以避免在“业务”逻辑中使用 If 语句并将条件移至 SQL 查询(或 EF 查询)。例如:

setAttribute('style',...)

这种方法在 EntityFramework 中实现也非常简单,如果你使用它。