如何从PowerShell传递凭据并在API方法中获取使用
解决PowerShell调用API时凭据传递与API端接收的问题
首先得指出你当前代码里的核心问题:你的API方法里用的System.Net.CredentialCache.DefaultCredentials和DefaultNetworkCredentials,获取的是API所在服务器进程(比如IIS应用池)的本地凭据,而不是客户端(PowerShell)传递过来的凭据。这就是为什么你在PowerShell里传了凭据,但API没用到的原因。
下面分两步帮你解决:
一、修改API端代码,接收并使用客户端传递的凭据
1. 确保API启用Windows认证
首先你需要在ASP.NET项目中启用Windows认证(如果还没开启的话):
- 对于ASP.NET Core:在
Program.cs里添加builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();,然后启用中间件app.UseAuthentication(); app.UseAuthorization(); - 对于传统ASP.NET:在Web.config里设置
<authentication mode="Windows" />,并确保匿名认证关闭。
2. 修改API方法,获取客户端凭据
修改你的UpdateComputerDescriptions方法,获取客户端传递的身份凭据,再传入UpdateDescriptionsAndTimestamp方法:
[HttpGet] [Authorize] // 加上这个确保只有认证用户能访问 public string UpdateComputerDescriptions() { // 获取客户端的Windows身份 var windowsIdentity = HttpContext.User.Identity as WindowsIdentity; if (windowsIdentity == null) { return "未通过Windows认证"; } // 使用客户端身份模拟执行操作(多数场景下无需明文密码) using (windowsIdentity.Impersonate()) { // 如果UpdateDescriptionsAndTimestamp需要NetworkCredential对象,可从身份中提取域和用户名 var clientCred = new NetworkCredential( windowsIdentity.Name.Split('\\')[1], "", // 注意:Windows认证无法获取明文密码,若方法必须要明文密码需改用其他认证方式 windowsIdentity.Name.Split('\\')[0] ); UpdateDescriptionsAndTimestamp(clientCred); return "done"; } }
补充:如果
UpdateDescriptionsAndTimestamp必须依赖明文密码,Windows认证的方式无法满足,这时候可以改用Basic认证(必须配合HTTPS保障安全),在API端解析请求头里的授权信息获取明文凭据。
二、PowerShell端正确传递凭据的方式
方式1:使用Invoke-WebRequest(推荐)
$url = "你的API完整地址" $username = "域\用户名" $password = ConvertTo-SecureString "你的密码" -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential ($username, $password) # 调用API并传递凭据 Invoke-WebRequest -Uri $url -Credential $credential -UseDefaultCredentials:$false
方式2:使用WebClient
$webclient = New-Object System.Net.WebClient $username = "域\用户名" $password = "你的密码" $domain = "你的域名称" $webclient.Credentials = New-Object System.Net.NetworkCredential($username, $password, $domain) # 如果PowerShell本身运行在有权限的用户身份下,也可以直接用默认凭据 # $webclient.UseDefaultCredentials = $true $webpage = $webclient.DownloadString($url) Write-Host $webpage
提示:如果你是在已经登录的目标用户身份下运行PowerShell,直接用
-UseDefaultCredentials(Invoke-WebRequest)或$webclient.UseDefaultCredentials = $true会更简便,无需手动输入密码。
三、调试验证步骤
- 在API端添加日志,输出
HttpContext.User.Identity.Name,确认客户端身份是否正确传递 - 在PowerShell中使用
Invoke-WebRequest加上-Verbose参数,查看请求的授权头是否正常发送 - 确保API服务器和客户端处于同一域或信任域环境中,避免Kerberos/NTLM认证失败
内容的提问来源于stack exchange,提问作者Bassie
相关产品推荐
相关产品推荐

