包含外部身份的EF Core关系

时间:2018-01-20 03:15:10

标签: entity-framework asp.net-web-api identityserver4

我正在努力改进我所拥有的业余爱好项目,并一直关注数据库关系。 目前我有2个解决方案:

  • GameStoreSolution:注册所有用户的游戏,游戏设备和分数
  • IdentityProvider:带有AspCoreIdentity的IdentityServer4项目,管理身份和身份验证

我的GameStore包含基本的Angular 5前端,以及受IdentityProvider服务器保护的WebApi服务器。

我无法弄清楚的是,我如何证明IdentityProvider提供的经过身份验证的用户与每个Store解决方案中的相关实体之间的关系?

目前我已经攻击它并将AspCoreIdentity复制到两个解决方案中并通过实体对象创建链接,例如下面:

public class GameDevice {
     public Guid Id {get; set;}
     public ApplicationUser User {get;set;}
}

这种方法有效,但如果你考虑它就很糟糕。

  1. 它强制IdentityProvider和Web App共享用户实体和可能的db

  2. IdentityProvider中的更改并导致Web App在未通过复制更改时抛出异常

  3. 其他网络应用程序使关系模型复杂化,甚至进一步导致更多麻烦

  4. 可能需要同时处理同一平台/服务器/ db以最大限度地降低失败风险

  5. 所以我的问题是,是否有更好的方法来管理与身份提供商服务的用户的关系?

2 个答案:

答案 0 :(得分:2)

让我们退后一步,忘记身份验证。没有它,您可以将用户信息存储在模型中。商业模式,因为这些信息是商业信息。当您显示包含用户信息的报告时,这是您需要的信息。它不包含任何有关身份验证或授权的信息。

现在使用Ids4添加安全性。让我们假设Ids4有自己的数据库,实际上它应该是这样的。在Ids4中创建用户并配置流和用户以授予访问权限。结果是可以登录的用户。那么,您将拥有两个单独的用户:登录用户和业务用户。

在继续之前,请记住,并非所有业务用户都需要登录。并非所有登录用户都可以访问此应用程序。

最后一步是将两者联系在一起。您应该使用sub声明。 但我宁愿添加包含特定应用程序的UserId的声明,例如http://myapp1/userid = 123 因为您可以确定此密钥在所有应用中都是唯一的,并且作为声明存在,因为它是OpenId Connect的一部分:在IdentityServer4中,openid范围是必需的(不需要同意,也不能撤销用户)。

现在关于冗余。实际上还没有。信息存储在两个位置,但不存储在同一数据库中。考虑到这一点,如果您使用外部登录(例如Google),那么您会遇到同样的问题,在这种情况下,您可以将信息复制到本地身份表中。

使用Ids4并没有太大的不同。但是,您不必将信息复制到另一个身份表,而是更新您的业务用户。但只有商业信息。使用UserInfo端点从Ids4请求用户信息。

保持两个环境分离是最简单的方法。所以,没有数据库关系。这适用于所有应用程序。 Ids4或您的应用程序中的更改并不会影响彼此。如果你愿意,你甚至可以用另一个oidc服务器替换Ids4。

从代码中删除了复杂性,它现在涉及到配置Ids4,这实际上是使用Ids4的一个重要原因:配置资源,范围和流程的灵活性。

一个缺点可能是您需要在Ids4上维护登录用户,而您需要在您的应用程序中维护的业务用户。如果您也想从应用程序管理登录用户,请使用API​​扩展Ids4以使其成为可能。

答案 1 :(得分:0)

您可以隐藏某些界面后面的Identity Provider / DB。这个接口返回某种DTO。 Web API使用接口,并将此DTO作为JSON返回给Angular应用程序。它使事情变得复杂,但是你有所需的抽象,而且API并不了解实体。