在Azure中的应用程序服务上运行时,我希望使用托管服务标识通过两组权限对Azure SQL Server进行身份验证。在我的服务中,我希望有一个读/写DBContext和一个只读DBContext。身份验证后是否有降级访问的方法?
我不一定可以访问带有只读副本的AG,所以我认为我不能使用applicationintent=readonly
,EXECUTE AS
似乎只适用于存储过程或函数。
还有其他建议吗?
我对EXECUTE AS不在存储过程/函数之外工作的说法是错误的(我发现此文档具有误导性,后来发现了这一点。
因此,我最终选择了以下解决方案:
-
创建一个没有登录的只读用户
CREATE USER [readonly_user] WITHOUT LOGIN ALTER ROLE [db_datareader] ADD MEMBER [readonly_user]
-
我创建了一个拦截器,用于查找要在连接字符串中设置的
applicationintent=readonly
标志public class SessionContextDbConnectionInterceptor: DbCommandInterceptor { /// <inheritdoc /> public override Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync( DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result, CancellationToken cancellationToken = new CancellationToken()) { if (eventData.Connection.ConnectionString.Contains("applicationintent=readonly", StringComparison.InvariantCultureIgnoreCase)) { command.CommandText = $"EXECUTE AS USER = 'readonly_user';n{command.CommandText};nREVERT;"; } return base.ReaderExecutingAsync(command, eventData, result, cancellationToken); } }
-
然后用DB上下文注册拦截器
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")) .AddInterceptors(new SessionContextDbConnectionInterceptor()));