问题描述
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:
或者您可以使用 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 中实现也非常简单,如果你使用它。