feat: 支持加密保护数据库连接字符串中的密码字段,便于配置中心使用。https://github.com/NewLifeX/NewLife.XCode/issues/14
This commit is contained in:
parent
2fe23f93d5
commit
a6a54119ea
|
@ -57,6 +57,7 @@ namespace XCode.DataAccessLayer
|
|||
String ConnName { get; set; }
|
||||
|
||||
/// <summary>链接字符串</summary>
|
||||
/// <remarks>内部密码字段已解密</remarks>
|
||||
String ConnectionString { get; set; }
|
||||
|
||||
/// <summary>数据库提供者。用于选择驱动</summary>
|
||||
|
|
|
@ -10,6 +10,7 @@ using NewLife.Configuration;
|
|||
using NewLife.Log;
|
||||
using NewLife.Model;
|
||||
using NewLife.Reflection;
|
||||
using NewLife.Security;
|
||||
using NewLife.Serialization;
|
||||
using NewLife.Threading;
|
||||
|
||||
|
@ -36,10 +37,18 @@ public partial class DAL
|
|||
|
||||
/// <summary>连接字符串</summary>
|
||||
/// <remarks>
|
||||
/// 内部密码字段可能处于加密状态。
|
||||
/// 修改连接字符串将会清空<see cref="Db"/>
|
||||
/// </remarks>
|
||||
public String ConnStr { get; private set; }
|
||||
|
||||
/// <summary>数据保护者</summary>
|
||||
/// <remarks>
|
||||
/// 用于保护连接字符串中的密码字段,在向IDatabase设置连接字符串前解密。
|
||||
/// 默认保护密码可通过环境变量或者配置文件的ProtectedKey项进行设置。
|
||||
/// </remarks>
|
||||
public ProtectedKey ProtectedKey { get; set; } = ProtectedKey.Instance;
|
||||
|
||||
private IDatabase _Db;
|
||||
/// <summary>数据库。所有数据库操作在此统一管理,强烈建议不要直接使用该属性,在不同版本中IDatabase可能有较大改变</summary>
|
||||
public IDatabase Db
|
||||
|
@ -522,10 +531,12 @@ public partial class DAL
|
|||
/// <remarks>Base64=>UTF8字节=>明文</remarks>
|
||||
/// <param name="connstr"></param>
|
||||
/// <returns></returns>
|
||||
private static String DecodeConnStr(String connstr)
|
||||
private String DecodeConnStr(String connstr)
|
||||
{
|
||||
if (String.IsNullOrEmpty(connstr)) return connstr;
|
||||
|
||||
connstr = ProtectedKey.Unprotect(connstr);
|
||||
|
||||
// 如果包含任何非Base64编码字符,直接返回
|
||||
foreach (var c in connstr)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NewLife.Core" Version="10.3.2023.503" />
|
||||
<PackageReference Include="NewLife.Core" Version="10.3.2023.510-beta2316" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="build\**" />
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<!--命名格式。Default/Upper/Lower/Underline-->
|
||||
<NameFormat>Default</NameFormat>
|
||||
<!--生成器版本-->
|
||||
<Version>11.8.2023.0503</Version>
|
||||
<Version>11.8.2023.0511</Version>
|
||||
<!--帮助文档-->
|
||||
<Document>https://newlifex.com/xcode/model</Document>
|
||||
</Option>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<!--命名格式。Default/Upper/Lower/Underline-->
|
||||
<NameFormat>Underline</NameFormat>
|
||||
<!--生成器版本-->
|
||||
<Version>11.8.2023.0503</Version>
|
||||
<Version>11.8.2023.0511</Version>
|
||||
<!--帮助文档-->
|
||||
<Document>https://newlifex.com/xcode/model</Document>
|
||||
</Option>
|
||||
|
|
|
@ -1,74 +1,89 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using NewLife;
|
||||
using XCode.DataAccessLayer;
|
||||
using Xunit;
|
||||
|
||||
namespace XUnitTest.XCode.DataAccessLayer
|
||||
namespace XUnitTest.XCode.DataAccessLayer;
|
||||
|
||||
public class DALTests
|
||||
{
|
||||
public class DALTests
|
||||
[Fact]
|
||||
public void LoadConfig()
|
||||
{
|
||||
[Fact]
|
||||
public void LoadConfig()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
DAL.LoadConfig(ds);
|
||||
DAL.LoadConfig(ds);
|
||||
|
||||
Assert.True(ds.ContainsKey("MSSQL"));
|
||||
Assert.True(ds.ContainsKey("MSSQL"));
|
||||
|
||||
var di = ds["MSSQL"];
|
||||
Assert.Equal("MSSQL", di.Name);
|
||||
Assert.Equal("Data Source=.;Initial Catalog=master;Integrated Security=SSPI", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.SqlServer", di.Type.FullName);
|
||||
Assert.Equal("System.Data.SqlClient", di.Provider);
|
||||
}
|
||||
var di = ds["MSSQL"];
|
||||
Assert.Equal("MSSQL", di.Name);
|
||||
Assert.Equal("Data Source=.;Initial Catalog=master;Integrated Security=SSPI", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.SqlServer", di.Type.FullName);
|
||||
Assert.Equal("System.Data.SqlClient", di.Provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadAppSettings()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
DAL.LoadAppSettings("appsettings.json", ds);
|
||||
[Fact]
|
||||
public void LoadAppSettings()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
DAL.LoadAppSettings("appsettings.json", ds);
|
||||
|
||||
Assert.True(ds.ContainsKey("sqlserver"));
|
||||
Assert.True(ds.ContainsKey("sqlserver"));
|
||||
|
||||
var di = ds["sqlserver"];
|
||||
Assert.Equal("sqlserver", di.Name);
|
||||
Assert.Equal("Server=127.0.0.1;Database=Membership;Uid=root;Pwd=root;", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.SqlServer", di.Type.FullName);
|
||||
Assert.Equal("SqlServer", di.Provider);
|
||||
}
|
||||
var di = ds["sqlserver"];
|
||||
Assert.Equal("sqlserver", di.Name);
|
||||
Assert.Equal("Server=127.0.0.1;Database=Membership;Uid=root;Pwd=root;", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.SqlServer", di.Type.FullName);
|
||||
Assert.Equal("SqlServer", di.Provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadAppSettings2()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
DAL.LoadAppSettings("appsettings.json", ds);
|
||||
[Fact]
|
||||
public void LoadAppSettings2()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
DAL.LoadAppSettings("appsettings.json", ds);
|
||||
|
||||
Assert.True(ds.ContainsKey("sqlite"));
|
||||
Assert.True(ds.ContainsKey("sqlite"));
|
||||
|
||||
var di = ds["sqlite"];
|
||||
Assert.Equal("sqlite", di.Name);
|
||||
Assert.Equal("Data Source=Data\\Membership.db;provider=sqlite", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.SQLite", di.Type.FullName);
|
||||
Assert.Equal("sqlite", di.Provider);
|
||||
}
|
||||
var di = ds["sqlite"];
|
||||
Assert.Equal("sqlite", di.Name);
|
||||
Assert.Equal("Data Source=Data\\Membership.db;provider=sqlite", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.SQLite", di.Type.FullName);
|
||||
Assert.Equal("sqlite", di.Provider);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadEnvironmentVariable()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
var envs = Environment.GetEnvironmentVariables();
|
||||
envs.Add("XCode_pgsql", "Server=.;Database=master;Uid=root;Pwd=root;provider=PostgreSql");
|
||||
[Fact]
|
||||
public void LoadAppSettingsWithProtected()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
DAL.LoadAppSettings("appsettings.json", ds);
|
||||
|
||||
DAL.LoadEnvironmentVariable(ds, envs);
|
||||
Assert.True(ds.ContainsKey("MySqlWithProtected"));
|
||||
|
||||
Assert.True(ds.ContainsKey("pgsql"));
|
||||
var dal = DAL.Create("MySqlWithProtected");
|
||||
Assert.Equal("KeyOfProtected", dal.ProtectedKey.Secret.ToStr());
|
||||
|
||||
var di = ds["pgsql"];
|
||||
Assert.Equal("pgsql", di.Name);
|
||||
Assert.Equal("Server=.;Database=master;Uid=root;Pwd=root;provider=PostgreSql", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.PostgreSQL", di.Type.FullName);
|
||||
Assert.Equal("PostgreSql", di.Provider);
|
||||
}
|
||||
Assert.Equal("Server=.;Membership=mysql;Uid=root;Pwd=$AES$xpZ49nBk5UscLCFyCx_BUg;provider=mysql", dal.ConnStr);
|
||||
Assert.Equal("Server=127.0.0.1;Membership=mysql;Uid=root;Pwd=Pass@word;CharSet=utf8mb4;Sslmode=none", dal.Db.ConnectionString);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadEnvironmentVariable()
|
||||
{
|
||||
var ds = new ConcurrentDictionary<String, DbInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
var envs = Environment.GetEnvironmentVariables();
|
||||
envs.Add("XCode_pgsql", "Server=.;Database=master;Uid=root;Pwd=root;provider=PostgreSql");
|
||||
|
||||
DAL.LoadEnvironmentVariable(ds, envs);
|
||||
|
||||
Assert.True(ds.ContainsKey("pgsql"));
|
||||
|
||||
var di = ds["pgsql"];
|
||||
Assert.Equal("pgsql", di.Name);
|
||||
Assert.Equal("Server=.;Database=master;Uid=root;Pwd=root;provider=PostgreSql", di.ConnectionString);
|
||||
Assert.Equal("XCode.DataAccessLayer.PostgreSQL", di.Type.FullName);
|
||||
Assert.Equal("PostgreSql", di.Provider);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"Url": "https://newlifex.com/",
|
||||
//"ProtectedKey": "KeyOfProtected",
|
||||
"ProtectedKey": "$base64$S2V5T2ZQcm90ZWN0ZWQ",
|
||||
"ConnectionStrings": {
|
||||
"sqlite": "Data Source=Data\\Membership.db;provider=sqlite",
|
||||
"MySQL.AppSettings": {
|
||||
|
@ -19,6 +21,7 @@
|
|||
"TDengine": {
|
||||
"connectionString": "Server=gz01.newlifex.com;Port=6030;Database=db;user=root;password=taosdata",
|
||||
"providerName": "TDengine"
|
||||
}
|
||||
},
|
||||
"MySqlWithProtected": "Server=.;Membership=mysql;Uid=root;Pwd=$AES$xpZ49nBk5UscLCFyCx_BUg;provider=mysql"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue