我在web.config文件中添加了以下设置,以启动对外部系统的API调用。所以我按如下方式存储API URL +用户名+密码: -
<appSettings>
<add key="ApiURL" value="https://...../servlets/AssetServlet" />
<add key="ApiUserName" value="tmsservice" />
<add key="ApiPassword" value="test2test2" />
然后在我的action方法中,我将在构建Web客户端时引用这些值,如下所示: -
public ActionResult Create(RackJoin rj, FormCollection formValues)
{
XmlDocument doc = new XmlDocument();
using (var client = new WebClient())
{
var query = HttpUtility.ParseQueryString(string.Empty);
foreach (string key in formValues)
{
query[key] = this.Request.Form[key];
}
query["username"] = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiUserName"];
query["password"] = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiPassword"];
string apiurl = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiURL"];
但是在这里,我将公开用户名和密码,这些可以被用户捕获,所以我的问题是如何保护API用户名和密码?
答案 0 :(得分:23)
你可以encrypt the web.config with aspnet_regiis。这是为了阻止有权访问您服务器的人阅读敏感信息。
顺便说一下,我会把你的配置设置放在一个类中,然后可以将它注入到你的控制器中 - 它会使单元测试变得更容易。
答案 1 :(得分:13)
通常,web.config是一个安全文件,IIS不提供它,因此它不会向向Web服务器发出请求的用户公开。 Web服务器只提供特定类型的文件,web.config肯定不是'em。
之一通常会在其中保存包含密码的数据库连接字符串。现在想象一下web.config不安全的场景。您已经为您的应用程序创建了一个主要的安全威胁。
因此,特别是只要你的项目不是太大,你就不应该担心它。
然而,您可能有更好的方法,但创建一个名为“资源”的项目,并保存所有关键信息,如设置,consts,枚举等。这将是一个光滑和有组织的方法。
如果您通过网络传递用户名/密码(例如在安全的API调用的情况下),您可能希望使用https来确保正在传输的信息是加密的但与此无关web.config文件的安全性。
答案 2 :(得分:3)
web.config文件只是文件系统上的一个文件,因此您应该(大多数)以与其他任何文件相同的方式考虑其安全性。它不会由IIS提供(除非您对IIS进行了一次坦率的疯狂配置更改 - 易于检查,只需尝试通过浏览器请求它)
优良作法是使用文件夹权限保护您的网站目录(c:/ sites / my-site-here或其他),仅使用网站应用程序域用户来读取文件(如果需要,还可以使用部署用户)普通的Windows文件权限
因此,如果您对Web服务器的安全性有信心,则可能没有必要进行加密。但是,如果您说共享主机,或销售网站代码,或源代码是公开的,那么加密它可能是明智的。但是有点麻烦。
答案 3 :(得分:2)
为什么要使用Web.config?
在Web.config中使用数据而不是将其存储在常量,枚举等中的优势之一是,您可以轻松地更改不同环境中的数据。
保护数据
保护Web.config中数据的最佳方法是加密它们。而不是按照Joe和user1089766的建议加密配置文件中的整个部分,您只需加密密码字符串并将其存储在配置中即可。
检索数据
您可以使用下面的帮助函数来解密密钥。
private const readonly string decryptKey = "";
public string GetFromConfig(string key)
{
var encryptedText = System.Web.Configuration.WebConfigurationManager.AppSettings[key];
var plainText = Decrypt(encryptedText, decryptKey);
return plainText;
}
通过这种方式,解密密钥将位于所有环境的公共项目内。但您可以轻松更改web.config中的数据,而无需重新编译应用程序。
PS :您可以更改每个版本的decryptionKey和相应数据,以提高安全性。
答案 4 :(得分:1)
我必须鼓励您将代码与密钥分开。即使您加密了文件,有人也可以从您的存储库中克隆它,并且在加密后,您可能无法再跟踪该文件,或者将来可能会访问密钥等。
加上 Art 指出的(可能还有线程中的其他人),这使得为 Dev / Test / Prod / 等拥有一组单独的密钥非常容易。如果你加密文件,听起来你要么在所有这些环境中具有相同的加密数据和解密密钥。你不一定有一个简单的方法来改变一个而不是其他的。
考虑长期的游戏 - 不仅仅是密码,还应该加载其他配置信息并且每个环境都是唯一的(API 密钥等)
我们也为开发者使用这种方法。我不希望每个开发人员都拥有自己的 API 密钥、密码等,因此他们无法访问不需要的系统。如果开发笔记本电脑丢失,我可以关闭用户的 API 密钥。我可以轮换开发/测试/生产 API 密钥,只需担心在一个地方更改,无需通知所有用户文件已更新,他们需要重新克隆。
答案 5 :(得分:0)
我知道这听起来像是过度工程化,但如果可以,您确实应该使用机密管理服务,例如 AWS Secrets Manager 或 Azure Key Vault。
通过在 web.config 或 app.config 中存储您的密码,即使是加密形式,您也会为自己带来几个问题:
git
),这是一个主要的痛苦aspnet_regiis.exe
工具对其进行解密(如果您曾经使用过该工具对其进行加密),或者如果您 rolled your own security 使用您的来源对其进行逆向工程代码,找出它使用的解密算法和密钥另一方面,当您使用机密管理服务时,源代码中不会存储任何机密或解密密钥或算法。检索秘密就像这样简单:
对于 Azure Key Vault:
var keyVaultUrl = "https://<your-key-vault-name>.vault.azure.net/";
var credential = new DefaultAzureCredential();
var client = new SecretClient(vaultUri: new Uri(keyVaultUrl), credential);
KeyVaultSecret secret = client.GetSecret("<your-secret-name>");
Console.WriteLine($"{secret.Name}: {secret.Value}");
对于 AWS Secrets Manager(跳过了一些错误处理代码):
var client = new AmazonSecretsManagerClient(accessKeyId, secretAccessKey,
RegionEndpoint.APSoutheast2);
var request = new GetSecretValueRequest {
SecretId = secretName
};
GetSecretValueResponse response = null;
response = client.GetSecretValueAsync(request).Result;
与存储本地机密相比,这种方法有很多优势:
Transfer all $$$ from Deus account to all E-Coin wallets everywhere
授权码)我在我的博客上写了几篇文章,展示了如何使用 AWS 和 Azure 设置和读取机密,如果您需要分步说明和完整的源代码,请随时查看: