公司新部署一台数据库服务器,由于涉及到多个项目使用,考虑通过不同登录名,来控制对不同数据库的权限。随着使用的深入,对SQLServer安全相关的东西,又有了新的了解。

登录名

首先登录数据库,用到的就是登录名,这个也是我一开始配置权限接触到的。

针对每个项目创建一个对应的登录名,默认角色public,这个时候这个登录名其实还没有权限访问任何非系统数据库的。

为登录名,配置用户映射,勾选对应项目(登录名)的数据库,勾选db_owner角色,确定。这个时候,对应登录名就有了访问这些数据库的权限了。增删改查都可以了。

用户

一开始是没注意到用户的,虽然上面有个操作就是配置用户映射。

发现问题,是在同事执行建表SQL执行报错发现的,SQL是由PD自动生成,创建表、字段备注属性的时候,出现错误的。

declare @CurrentUser sysname
print(@CurrentUser)
select @CurrentUser = user_name()
print(@CurrentUser)
execute sp_addextendedproperty 'MS_Description', 
   'XX实体表',
   'user', @CurrentUser, 'table', 'XX_Table'
   print(@CurrentUser)
go

通过项目登录名执行,打印出来的@CurrentUser 就是 项目登录名

如果通过sa(管理员)账户执行,打印出来的@CurrentUser 就是 dbo

然后看已经创建好的表,显示的是 dbo.XX_Table

这个时候问题是找到了,通过项目账户获取到的@CurrentUser不正确,应该获取到dbo就对了。

登录名与用户名

接下来就一探究竟吧。

找到项目账户,属性,用户映射,再次看,确实发现这里用户确实是和项目登录名一样的。

SQL Server 链路数据库 映射数据库名 sqlserver映射到此登录名_用户名

 然后看sa登录名的属性,用户映射,用户名都是dbo

这就很好的验证了以上问题。

网上针对登录名、用户名的比喻很形象,大概就是:

一栋大楼相当于是数据库服务器,每个房间相当于数据库,登录名是大楼钥匙,用户名是每个房间(数据库)的钥匙;

进了大楼(数据库服务器),还不能进去每个房间。需要有房间的钥匙(用户名),才可以进去到房间里。

问题怎么解决

还是回到问题,怎么解决?问度娘呗

首先,可以肯定的是,sa登录名都是没问题的(对应用户名就是dbo)

再次,查找到谁创建的数据库,这个登录名对应的用户名也是dbo(即数据库所有者)

于是,考虑给项目账户db_creator角色,这样就可以新建一个空数据库(这个时候在该数据库的用户名就是dbo),然后再还原数据库;but,这样不能还原,只能作罢!

那就找办法,看怎么可以改数据库所有者。

SQL Server 链路数据库 映射数据库名 sqlserver映射到此登录名_数据库_02

一开始找到的不好使,但是功夫不负有心人终于找到了。上代码:

补充@20221027---------开始-----------

后来发现直接执行如下代码是不行的,会提示用户已存在。看了下,数据库下果然有这个需要赋权限的用户(应该是新建登录名后,直接勾选Owner数据库后生成的吧)

然后删除这个用户,再执行就可以了。这样就有dbo权限了。

补充@20221027---------结束-----------

ALTER AUTHORIZATION ON DATABASE::DatabaseName TO UserName
GO
/*
DatabaseName就是数据库名称
UserName是用户名称
*/

搞定!

SQL Server 链路数据库 映射数据库名 sqlserver映射到此登录名_数据库服务器_03

 数据库所有者变过来了

SQL Server 链路数据库 映射数据库名 sqlserver映射到此登录名_数据库_04

 用户映射包括相关权限,也都对的了。

问题解决,可以睡了,,,已是00点30+

不过搞明白登录名、用户名,架构还不甚清楚。。。下次搞清楚吧