【问题标题】:Database Schema for Claims Authentication声明身份验证的数据库模式
【发布时间】:2013-10-11 08:30:43
【问题描述】:

在数据库中,我有以下表格:USERS、USERS_PROFILES、USERS_CLAIMS。

create table dbo.USERS
(
  Id int identity not null, 
  Username nvarchar (120) not null,
  Email nvarchar (120) not null
);
create table dbo.USERS_PROFILES
(
  Id int not null,
  [Name] nvarchar (80) not null
);
create table dbo.USERS_CLAIMS
(
  Id int not null,
  [Type] nvarchar (200) not null,
  Value nvarchar (200) not null,
);

我正在使用声明授权。当用户注册并创建身份时。 身份包含声明,每个声明都有一个类型和一个值:

UsernameType > 来自 USERS 的用户名 电子邮件类型 > 来自用户的电子邮件 NameType > 来自 USERS_PROFILES 的名称 RoleType > 直接来自 USERS_CLAIMS

所以我从 3 个表中的许多列创建身份。

我最终得到了这个,因为我迁移到了声明身份验证。

问题

我应该将用户名、电子邮件和姓名移至 USERS_CLAIMS 吗? USERS_PROFILES 表将消失... 并且 USERS 表将仅包含诸如“UserId、LastLoginDate、CreatedDate、...”之类的信息

如果我想通过用户名获取用户,我只会得到用户名类型的声明 ...

如果我想登录用户,我只需获取所有声明并创建身份。

所以身份模型与 SQL 表非常相似。

这有意义吗?你会如何设计桌子?

谢谢你, 米格尔

【问题讨论】:

    标签: sql database-design


    【解决方案1】:

    您正在创建一个键值存储。它们是用 SQL 查询的噩梦。考虑通过USER_CLAIMS 表上的值查询用户属性的难度。示例:

    -- Users with name and email by username
    SELECT p.ID, p.Username, p.Name, p.Email, u.LastLoggedIN
    FROM USER_PROFILES p
    INNER JOIN Users u on p.ID = u.ID
    WHERE p.ID = @UserID
    
    -- Users with name and email by username with a claims table
    -- Does not specify whether there is only one email, so this could return multiple
    -- rows for a single user.
    SELECT p.ID, cUName.Value as Username, cName.Value as Name, cEMail.Value as Email, u.LastLoggedIN
    FROM Users u
    LEFT OUTER JOIN USER_CLAIMS cName ON u.ID = cName.ID and cName.[Type] = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'
    LEFT OUTER JOIN USER_CLAIMS cUName ON u.ID = cUName.ID and cUName.[Type] = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier'
    LEFT OUTER JOIN USER_CLAIMS cEmail ON u.ID = cEmail.ID and cEmail.[Type] = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email'
    WHERE p.ID = @UserID
    

    【讨论】:

    • 是的,这正是我担心的......我是否应该为角色创建一个 Roles 表并将其他信息存储在 USERS 表中?然后将所有这些信息迁移到我的应用程序上的声明身份?
    • 是的。您通过声明呈现数据这一事实不应显着改变您的架构。使数据存储易于访问和操作。从单行返回多个声明比从多个声明返回单行要容易得多。
    【解决方案2】:

    一个用户可以拥有多个个人资料吗?如果没有,则不需要“USERS_PROFILES”表。保留“USERS”表中的“用户名”和“电子邮件”列。如果您将它们放在“USERS_CLAIMS”表中,您将在用户提出索赔时存储冗余信息。

    我不确定您希望对您的用户进行什么样的跟踪,但我建议您使用单独的表格来跟踪用户何时登录。如下所示:

    CREATE TABLE USERS_LOG (user_id INT, log_in DATETIME);
    

    然后,您可以删除“USERS”表中的“LastLoginDate”,并进行联接以获取用户上次登录的时间。它会为您提供更多跟踪用户的方法,而您不会通过不断更新它在您的“用户”表上创建块。

    【讨论】:

    • 为什么不使用我已经拥有的 Logging 表而不是 USERS_Log 表?在每条记录上都有一个标志,我可以为该用户选择项目......也许更灵活并使用已经存在的表?
    • 用户名、生日等等……你会把它放在USERS表中吗? USERS 和 USER_Profiles 是拆分表...在 USERS 上,我放置了身份验证工作所需的所有信息。在个人资料上,我放置了其他信息,例如姓名,生日,...这会因应用程序而异...但是 USERS 表是相同的...这种方式更容易维护和更改从一个应用程序到另一个应用程序
    • 关于 USER_CLAIMS。这仅适用于角色吗?或者对于所有不被查询的东西?事实上我从来不知道......也许我需要按角色查询用户......我真的不确定最好的方法。
    • @MDMoura 将生日、用户名等放在“USERS”表中。听起来您真的不需要“USERS_PROFILES”表,因为所有用户只有一个配置文件。您不必担心仅使用“USERS”表进行身份验证,因为表上的 READS 不会相互阻塞。如果您已经有一个日志记录表,请使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    相关资源
    最近更新 更多