如何获取Azure上SQL Server的所有活动IP地址并实现数据库切换展示功能
如何获取Azure上SQL Server的所有活动IP地址并实现数据库切换展示功能
嘿,我来帮你搞定这个需求!你的Blazor+C#应用要实现切换数据库并展示对应SQL Server的活动IP,其实拆成两大步骤就能轻松实现,我给你详细捋一遍:
第一步:获取资源组下的所有SQL数据库(关联对应Server)
首先你需要用到Azure的管理类库,先在Blazor项目里安装两个核心NuGet包:Azure.ResourceManager.Sql(用来操作SQL资源)和Azure.Identity(用来做安全身份验证,推荐用这个代替硬编码凭据)。
接下来可以写个服务类,封装获取资源组下数据库的逻辑:
using Azure.Identity; using Azure.ResourceManager; using Azure.ResourceManager.Sql; public class AzureSqlService { // 获取指定资源组下的所有SQL数据库,同时返回所属Server的信息 public async Task<List<(string DatabaseName, string ServerName, string ServerId)>> GetDatabasesInResourceGroup(string resourceGroupName) { // 用DefaultAzureCredential做身份验证:本地开发用Azure CLI登录,部署到Azure后用托管身份 var armClient = new ArmClient(new DefaultAzureCredential()); var resourceGroup = await armClient.GetResourceGroupAsync(resourceGroupName); var sqlDatabases = await resourceGroup.GetSqlDatabases().GetAllAsync().ToListAsync(); var dbList = new List<(string, string, string)>(); foreach (var db in sqlDatabases) { // 获取数据库所属的SQL Server资源 var sqlServer = await db.GetParentResourceAsync<SqlServerResource>(); dbList.Add((db.Data.Name, sqlServer.Data.Name, sqlServer.Id.ToString())); } return dbList; } }
注意:要给你的应用分配权限——如果部署在Azure App Service,启用托管身份后,给这个身份加「SQL Server参与者」或「读者」权限到目标资源组;本地开发的话,确保你用Azure CLI登录的账号有对应的权限。
之后在Blazor组件里,你可以把这个数据库列表绑定到下拉框,让用户选择:
<select @bind="SelectedServerId" @onchange="OnDatabaseSelected"> @foreach (var db in Databases) { <option value="@db.ServerId">@db.DatabaseName (所属Server: @db.ServerName)</option> } </select> @code { [Inject] private AzureSqlService SqlService { get; set; } private List<(string DatabaseName, string ServerName, string ServerId)> Databases { get; set; } = new(); private string SelectedServerId { get; set; } protected override async Task OnInitializedAsync() { // 替换成你的资源组名称 Databases = await SqlService.GetDatabasesInResourceGroup("your-resource-group-name"); } }
第二步:根据选中的数据库获取对应SQL Server的IP地址
这里分两种常见场景,你可以根据需求选:
场景1:获取SQL Server的防火墙允许IP规则(最常用)
如果要展示的是允许访问该SQL Server的IP范围,继续在AzureSqlService里加方法:
// 获取指定SQL Server的防火墙IP规则 public async Task<List<string>> GetSqlServerFirewallIps(string serverId) { var armClient = new ArmClient(new DefaultAzureCredential()); var sqlServer = await armClient.GetSqlServerResource(new ResourceIdentifier(serverId)); var firewallRules = await sqlServer.GetSqlFirewallRules().GetAllAsync().ToListAsync(); var ipList = new List<string>(); foreach (var rule in firewallRules) { // 单个IP的话,起始和结束IP相同;范围的话拼接成区间 if (rule.Data.StartIpAddress == rule.Data.EndIpAddress) { ipList.Add(rule.Data.StartIpAddress); } else { ipList.Add($"{rule.Data.StartIpAddress} - {rule.Data.EndIpAddress}"); } } return ipList; }
场景2:获取当前连接到SQL Server的活动客户端IP
如果要展示的是正在和SQL Server建立连接的客户端IP,需要直接连接数据库执行查询。你可以把数据库连接字符串存在Azure Key Vault里(和你之前尝试的逻辑衔接),先加获取密钥的方法:
using Azure.Security.KeyVault.Secrets; // 从Key Vault获取数据库连接字符串 public async Task<string> GetConnectionStringFromKeyVault(string vaultUrl, string secretName) { var secretClient = new SecretClient(new Uri(vaultUrl), new DefaultAzureCredential()); var secret = await secretClient.GetSecretAsync(secretName); return secret.Value.Value; } // 获取活动连接的客户端IP public async Task<List<string>> GetActiveConnectionIps(string connectionString) { var ipList = new List<string>(); using var conn = new SqlConnection(connectionString); await conn.OpenAsync(); // 查询SQL Server的动态管理视图,获取唯一的客户端IP var query = @" SELECT DISTINCT client_net_address FROM sys.dm_exec_connections WHERE client_net_address IS NOT NULL"; using var cmd = new SqlCommand(query, conn); using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { ipList.Add(reader.GetString(0)); } return ipList; }
注意:要给应用的身份加Key Vault的「密钥读取者」权限,同时确保连接字符串对应的账号有查询sys.dm_exec_connections的权限。
最后在Blazor组件里补充选中后的逻辑,把IP地址展示出来:
@if (IpAddresses != null && IpAddresses.Any()) { <h3>对应IP地址</h3> <ul> @foreach (var ip in IpAddresses) { <li>@ip</li> } </ul> } @code { private List<string> IpAddresses { get; set; } private async Task OnDatabaseSelected() { // 场景1:获取防火墙IP IpAddresses = await SqlService.GetSqlServerFirewallIps(SelectedServerId); // 场景2:获取活动连接IP(需要先从Key Vault拿连接字符串,替换成你的Vault地址和密钥名称规则) // var connString = await SqlService.GetConnectionStringFromKeyVault("https://your-vault.vault.azure.net/", $"sql-conn-{SelectedServerId}"); // IpAddresses = await SqlService.GetActiveConnectionIps(connString); StateHasChanged(); } }
备注:内容来源于stack exchange,提问作者Natashanoob
相关产品推荐
相关产品推荐

