如何在C#中通过Microsoft Web服务扩展访问控制面板Web凭据
访问Windows控制面板Web凭据的C#实现
首先明确:.NET官方库中不存在WebCredentials静态类,没法像Environment.Example那样直接通过静态属性读取Web凭据。要访问Windows凭据管理器里的Web凭据,得用以下两种方式:
方案1:用第三方NuGet库简化操作
推荐使用CredentialManagement包,它封装了Windows凭据管理的API,不用自己写P/Invoke代码:
- 在Visual Studio的NuGet包管理器中安装:
Install-Package CredentialManagement - 示例代码:
using CredentialManagement; // 加载所有Web类型凭据 var credentialSet = new CredentialSet { Type = CredentialType.DomainPassword }; if (credentialSet.Load()) { foreach (var cred in credentialSet) { Console.WriteLine($"目标地址: {cred.TargetName}, 用户名: {cred.UserName}, 密码: {cred.Password}"); } }
方案2:直接调用Windows API(无第三方依赖)
如果不想引入外部库,可以用P/Invoke直接调用Windows的CredEnumerate等API:
using System; using System.Runtime.InteropServices; public static class CredentialHelper { [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr pCredentials); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool CredFree(IntPtr pCredentials); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct Credential { public int Flags; public int Type; public IntPtr TargetName; public IntPtr Comment; public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; public int CredentialBlobSize; public IntPtr CredentialBlob; public int Persist; public int AttributeCount; public IntPtr Attributes; public IntPtr TargetAlias; public IntPtr UserName; } public static void ListWebCredentials() { int credentialCount; IntPtr credentialListPtr; // 枚举所有Web凭据("Web:"是过滤器,指定只获取Web类型的凭据) if (CredEnumerate("Web:", 0, out credentialCount, out credentialListPtr)) { for (int i = 0; i < credentialCount; i++) { IntPtr credPtr = Marshal.ReadIntPtr(credentialListPtr, i * IntPtr.Size); Credential cred = Marshal.PtrToStructure<Credential>(credPtr); string target = Marshal.PtrToStringUni(cred.TargetName); string userName = Marshal.PtrToStringUni(cred.UserName); // 密码是Unicode字符串,所以要除以2计算长度 string password = Marshal.PtrToStringUni(cred.CredentialBlob, cred.CredentialBlobSize / 2); Console.WriteLine($"目标: {target}, 用户名: {userName}, 密码: {password}"); } // 释放API分配的内存 CredFree(credentialListPtr); } else { int errorCode = Marshal.GetLastWin32Error(); Console.WriteLine($"读取凭据失败,错误码: {errorCode}"); } } } // 调用示例 CredentialHelper.ListWebCredentials();
注意事项
- 你已经获取了管理员权限,这是读取所有凭据的必要条件,普通权限可能无法访问部分系统凭据。
- Web凭据是一个集合,不是单个属性,所以没法通过类似
WebCredentials.Passwords的方式直接获取,必须通过枚举的方式遍历所有凭据条目。
内容的提问来源于stack exchange,提问作者Fish
相关产品推荐
相关产品推荐

