问题
I have a dev site with Basic Auth enabled. I am get to GET a page using the following to add basic auth to the headers:
$creds = "$($BASIC_AUTH_USER):$($BASIC_AUTH_PASS)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($creds))
$basicAuthValue = "Basic $encodedCreds"
$headers = @{
Authorization = $basicAuthValue
}
$login = Invoke-WebRequest $url -SessionVariable session -UseBasicParsing -Headers $headers
But I am unable to post to the same URL:
$fields = @{ Email = $SITE_USER; Password = $SITE_PASS; }
$login = Invoke-WebRequest -Uri $url -Method POST -WebSession $session -Body $fields -UseBasicParsing -Headers $headers
I get a 401 Unauthorized back. Everything works fine if I disable basic auth on the site. So I know it isn't a server issue. I am able to POST using my browser.
Edit: So it seems basic auth is working correctly when I debug on the server. But my server returns a redirect, which is then causing Invoke-Webrequest to interpret that as a 401.
Any idea on why this may not be working?
回答1:
You get this behaviour because of the redirect; when making this additional request to the redirect location the authorization header doesn't get included.
For this reason PowerShell 6.0.0 added the PreserveAuthorizationOnRedirect parameter.
Indicates the cmdlet should preserve the Authorization header, when present, across redirections.
By default, the cmdlet strips the Authorization header before redirecting. Specifying this parameter disables this logic for cases where the header needs to be sent to the redirection location.
Invoke-WebRequest reference
As an alternative, if you are not on PowerShell 6, you can work around it via a more lowlevel script using System.Net.WebRequest
wich defines a property AllowAutoRedirect
that can be set to False
in order to skip the redirect after a successful POST, avoiding the 401 error.
Notice that you have to take care of things like the data/body formatting (json, form-urlencoded, ...) and http-headers yourself.
The script will look like here below.
Notice the line with AllowAutoRedirect = $false
.
$creds = "$($BASIC_AUTH_USER):$($BASIC_AUTH_PASS)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($creds))
$basicAuthValue = "Basic $encodedCreds"
$url = "http://your.url"
$request = [System.Net.WebRequest]::CreateHttp($url);
$request.Method = "post"
$request.Headers.Add("Authorization", $basicAuthValue)
$request.AllowAutoRedirect = $false
$body = "your formatted data goes here"
$bytes = [System.Text.Encoding]::UTF8.GetBytes($body);
$stream = $request.GetRequestStream()
$stream.Write($bytes, 0, $bytes.Length);
$stream.Close();
$request.GetResponse();
来源:https://stackoverflow.com/questions/52637039/invoke-webrequest-gets-401-on-post-but-not-on-get-with-basic-auth