【问题标题】:What is the best place to inject the db password to the default EF connection string将 db 密码注入默认 EF 连接字符串的最佳位置是什么
【发布时间】:2023-03-04 11:20:01
【问题描述】:

实体数据模型向导说:

此连接字符串似乎包含连接数据库所需的敏感数据(例如密码)。在连接字符串中存储敏感数据可能存在安全风险。您想在连接字符串中包含这些敏感数据吗?

我选择了否,我在我的 Web.config 中发现了以下生成的新连接字符串:

 <add name="eMarket_DBEntities" connectionString="metadata=res://*/App_Code.EFModel.csdl|res://*/App_Code.EFModel.ssdl|res://*/App_Code.EFModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\sqlexpress;initial catalog=eMarket_DB;user id=sa;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient;" />

也在 Web.config 中:

  <entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />

如何以及在哪里最好将密码一次性传递为 EF 的默认值?

【问题讨论】:

    标签: c# asp.net sql-server vb.net entity-framework


    【解决方案1】:

    有两种方法可以在 Web.Config 中不包含密码。

    1. 在 IIS 的主机设置中输入密码。 IIS 为每个主机多保留一个主机配置,并且此主机配置中的所有设置都在 web.config 之前应用。唯一的问题是,只有管理员才能通过 IIS 管理控制台进行修改。

    2. 无密码连接字符串将使用应用程序池标识用户登录。您可以创建一个 windows 用户并将其设置为应用程序池标识。并授予对您网站内容文件夹的读取权限。并在 SQL 数据库中添加此用户并使此用户成为 db-owner。这是托管站点的最安全方式,因为每个应用程序池都在隔离中运行,并且可以为每个应用程序授予更多权限。唯一的问题是,任务管理器不再显示工作进程的站点名称。

    在共享主机中,任何可以访问控制面板的人都可能可以访问所有内容,您几乎无法保护它,但我们就是这样做的。

    1. 我们为开发人员创建单独的 FTP 登录以上传代码。
    2. 管理员设置了配置文件,开发人员永远不会上传 web.config。如果他们上传错误,管理员将登录到某个控制台或 ftp 并修改 web.config
    3. 不应授予开发人员对共享主机控制面板的管理员访问权限。设置网站以及上传代码和编辑 web.config 必须由管理员完成。
    4. Windows Azure 网站允许您在管理控制面板中修改 web.config。

    【讨论】:

    • 感谢您的回答,如果您可以为拥有共享主机但无权更新主机配置或 IIS 的穷人添加第三条建议,那将是完美的。
    • 我的意思是根据服务器访问限制尽可能安全。
    • @AkashKava,感谢您更新答案,您说“开发人员永远不会上传 web.config”,这意味着密码将存储在 Web.Config 中,对吗?回到我的问题的第一部分,EF 建议不要将密码存储在 Web.config 中。为什么?应用范围内有没有更好的地方。
    • 不,除了 web.config 之外,没有其他方法可以存储密码,或者我已经向您展示了其他两种方式。您可以尝试加密 web.config。
    • 开发人员应该能够修改 Web.config 的实际原因有很多。这条规则不应该更细化,并简单地指定在发布时进行 Web.config 转换以从 Web.config 中删除任何开发配置字符串吗?
    【解决方案2】:

    在初始化实体时,我在Web.config文件中传递了使用相同格式构造的连接字符串:

    String EntityConnectionString = String.Format("metadata=res://*/App_Code.EFModel.csdl|res://*/App_Code.EFModel.ssdl|res://*/App_Code.EFModel.msl;provider=System.Data.SqlClient;provider connection string='data source={0};initial catalog={1};persist security info=True;user id={2};password={3};multipleactiveresultsets=True;App=EntityFramework;Enlist=false'", ServerName, DatabaseName, DatabaseUserName, DatabasePassword);
    
        EntityContainer EntityDB = new EntityContainer(EntityConnectionString);
    

    【讨论】:

    • 感谢您的回答,您每次初始化实体时都这样做吗?我正在寻找一个默认的安全位置来传递密码。
    • 是的,实际上:我已经将 EntityConnectionString 作为一个属性,所以如果我需要在我的应用程序的多个位置初始化实体,我只需调用第二行。
    • DatabasePassword 从何而来?它是硬编码的吗?我问是因为那不再安全了。字符串文字很容易被反编译。
    • 你在哪里写的第一行?
    • @Ala,我有一个通用类,用于存储我的通用属性,以便通过我的应用程序访问。
    【解决方案3】:

    您可以将完整的连接字符串与密码一起使用,但对其进行加密,而不是将密码注入 web.config 中的连接字符串,如 this question 中所述。

    【讨论】:

      猜你喜欢
      • 2017-10-31
      • 2015-09-16
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 2013-04-28
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多