问题描述
我一直在按照Microsoft Identity Platform文档中的步骤操作,以使用.Net Core 2.1 API作为后端在我们现有的Angular SPA上启用Azure AD身份验证。
https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-overview
基础知识现在可以使用了,但是我有一个问题,我找不到一个好的答案。
在当前系统中,我们需要保留一个现有的“用户和权限”模型。我们可以设置2.000种不同的用户权限,并且在模型中广泛使用了User对象。
因此,我需要在我们的上下文中将Azure AD帐户耦合到给定的User对象。
我们现有的身份验证解决方案在JWT中拥有用户标识符作为声明,并且在API中验证了令牌后,我可以使用该声明针对请求设置当前用户上下文。
最明显的解决方案是在Azure返回的id令牌中使用“ preferred_username”声明。因此,在API方面,在JWT身份验证通过令牌后,我更改了SetCurrentUserMiddleware中的逻辑,以基于AzureAD电子邮件查找用户-并基于此设置用户上下文。中间件类的摘录
public async System.Threading.Tasks.Task Invoke(HttpContext context)
{
var currentPrincipal = context.User;
if(currentPrincipal != null)
{
if(currentPrincipal.Identity.IsAuthenticated)
{
if(currentPrincipal.HasClaim((x) => x.Type == "preferred_username"))
{
var email = currentPrincipal.FindFirst((x) => x.Type == "preferred_username").Value;
if (!String.IsNullOrEmpty(email))
CurrentUser = new User { WindowsUserName = email }.FetchOne();
}
}
}
}
给我带来的好处是:
- 当我们系统中的管理员创建新用户时,管理员很容易找到与用户帐户相关联的电子邮件,从而进行耦合。
- 该电子邮件已在MS的登录过程中使用-因此必须假定是唯一的。
- 客户只需要使用正确的配置(在Azure和我们的应用程序中)在Azure应用程序注册中注册我们的应用程序,即可使用。
我们的解决方案以多种方式部署。有些客户由我们托管,在每个客户的不同域中,有些则全部由内部部署
现在出现的问题是,这是否是首选方法,以及这是否是安全的方法。
或者还有更好的替代方法,可以将Azure Ad / Identity Platform与本地用户数据库进行映射。
我希望有人能给我一些提示或一些好的资源。
最好的问候 /安德斯
解决方法
可以使用用户主体名称/电子邮件进行初始映射,但是您应该存储用户的oid或子声明,而不是将来将其映射,因为它们是不可变的。 可以更改用户的UPN /电子邮件,因此它不是稳定的标识符。
oid声明(aka objectId)是唯一的不可变ID,用于标识用户,例如在Microsoft Graph API中。 子声明(也称为名称标识符)也是唯一的不可变ID,但是您的应用获得的值对该应用来说是唯一的,因此另一个应用在这里将获得不同的值。
通常,我建议存储objectId,因为这样可以在需要时从MS Graph API查询数据。
ID令牌参考:https://docs.microsoft.com/en-us/azure/active-directory/develop/id-tokens#payload-claims