老板说我们需要更频繁地更改我们的 SQL Server 帐户密码,而不是根本不更改。在我们发现我们的一个 web.config 文件可能在一个多月前遭到破坏后,他昨天决定这样做。它包含三个数据库的凭据,所有三个密码都是几年前的(根据密码中包含的年份判断)。
所以如果我有两个不同的 DBA 需要处理,每个都需要一个耗时的票证过程来更改密码,而一个 Web 服务器管理员需要一个类似的耗时过程,似乎没有办法改变所有三个 SQL Server 帐户密码,无需大量停机时间即可更新站点的 web.config。他希望我们现在每 3 个月执行一次。
因此,我向 DBA 建议,在这个示例中,我们应该为每个数据库设置两个帐户,一个在 99% 的时间里是事件的,一个是禁用的。然后每 3 个月,对于每个数据库,我可以请求 DBA 启用备用帐户并为他们提供新密码。然后我可以请求指向新帐户的 web.config 更新。网站更新后,DBA 可以禁用不再使用的三个帐户。
这是一种常见的做法吗?有专门的术语吗?有更好的主意吗?因为这个想法在这里遭到了一些反对。最后,为什么 SQL Server(或任何类似技术)不选择性地允许旧密码在帐户密码更改后短时间(比如一个小时)继续存在,以在我们想要的这种情况下提供帮助避免停机?
感谢您走到这一步!
最佳答案
我最近通过以下顺序解决了这个问题。
- 将授予个人登录名/用户的所有权限转换为基于角色的权限(详见下文)。
- 使用与第一个不同的密码创建第二个登录名/用户(如您所建议的);将他们添加到该角色。
- 让您的应用程序过渡到第二次登录。
- 验证您在第一次登录时没有看到任何登录事件。
- 更改首次登录的密码(如果您希望将安全表面区域保持得尽可能小,也可以完全放弃)。
至于“创建角色并将权限转移给它”位,这是我使用的脚本:
declare @user sysname = '<your user here>',
@role sysname = '<your role here>';
-- no changes should be necessary below here
select concat('CREATE ROLE ', quotename(@role), ' AUTHORIZATION [dbo];') AS [grant], '' AS [revoke], '' AS [permission_name], NULL AS [class_desc]
union all
select concat('ALTER ROLE ', quotename(@role), ' ADD MEMBER ', QUOTENAME(@user), ';'), '', '', null
UNION all
select concat('GRANT ', permission_name collate database_default, ' ON ',
CASE class_desc
when 'OBJECT_OR_COLUMN' then 'OBJECT::'
when 'TYPE' then 'TYPE::'
END,
QUOTENAME(
CASE class_desc
when 'OBJECT_OR_COLUMN' then OBJECT_SCHEMA_NAME(major_id)
when 'TYPE' then (SELECT SCHEMA_NAME([schema_id]) FROM sys.[types] WHERE [user_type_id] = [major_id])
END), '.',
quotename(
CASE class_desc
when 'OBJECT_OR_COLUMN' then object_name(major_id)
when 'TYPE' then TYPE_NAME(major_id)
END
),
' TO ', QUOTENAME(@role), ';'
),
CONCAT('REVOKE ', permission_name collate database_default, ' ON ',
CASE class_desc
when 'OBJECT_OR_COLUMN' then 'OBJECT::'
when 'TYPE' then 'TYPE::'
END,
QUOTENAME(
CASE class_desc
when 'OBJECT_OR_COLUMN' then OBJECT_SCHEMA_NAME(major_id)
when 'TYPE' then (SELECT SCHEMA_NAME([schema_id]) FROM sys.[types] WHERE [user_type_id] = [major_id])
END), '.',
quotename(
CASE class_desc
when 'OBJECT_OR_COLUMN' then object_name(major_id)
when 'TYPE' then TYPE_NAME(major_id)
END
),
' FROM ', QUOTENAME(@user), ';'
), [permission_name], [class_desc]
from sys.database_permissions
where grantee_principal_id = user_id(@user)
AND [permission_name] <> 'CONNECT'
ORDER BY [permission_name];
在我的例子中,我只需要担心对象和用户定义类型的权限;如果您拥有的不止于此,则必须对它们负责。但是上面会生成一个包含四列的结果集。 grant
列将是创建角色的 SQL,将您指定的用户添加到角色,然后授予角色该用户当前拥有的所有权限。 revoke
列将是从用户那里取消这些相同权限的 SQL。其他两列只是为了我的理智,因为我正在开发脚本以确保我没有遗漏任何内容。
一旦您运行了上述所有操作(请在进入生产环境之前在非生产环境中对其进行测试!),您的应用程序将利用该角色获得 它的权限。之后,您应该能够自信地按照适合您需要的节奏继续执行上述计划的其余部分。
关于asp.net - 更改数据库密码和避免网站停机的流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44599307/