1

I'm running into an issue trying to use the Invoke-RestMethod command in PowerShell 7. I can get it to run fine in PowerShell 5.1, but 7 gives me a 401 - Unauthorized message.

Here's the command for PowerShell 5.1:

Invoke-RestMethod "http://internalServer/api/job?name=testJob" -Method GET -UseDefaultCredentials -ContentType "application/JSON"

Here's the command for PowerShell 7:

Invoke-RestMethod "http://internalServer/api/job?name=testJob" -Method GET -UseDefaultCredentials -ContentType "application/JSON" -AllowUnencryptedAuthentication

The api is hosted on an internal server that uses Windows Authentication. When I track the requests through Fiddler, both commands seem to get the 401 response, but PowerShell 5.1 uses the response to generate an Authorization: Negotiate YII{token} header whereas PowerShell 7 stops and returns an error. Has anyone else encountered this before?

JR_M
  • 127
  • 1
  • 8

1 Answers1

1

As indicated in the comments, there is a redirect going on here. By default, authentication won't survive a redirect, but you can control that with the -PreserveAuthorizationOnRedirect parameter to Invoke-RestMethod:

$irmParams = @{
  Uri = "http://internalServer/api/job?name=testJob"
  Method = 'GET'
  UseDefaultCredentials = $true
  ContentType = 'application/json'
  PreserveAuthorizationOnRedirect = $true # <== Should be your solution
  AllowUnencryptedAuthentication = $true # <=== You should not be using this :)
}

Invoke-RestMethod @irmParams

Thanks to some additional legwork by OP, -PreserveAuthorizationOnRedirect:

Will only keep the authentication headers for requests made to a Uri that includes the original Uri up to the last /. What the documentation doesn't include is that the subsequent Uri's must also match the case of the original Uri.

In OP's case, the redirection was changing the case of the original Uri, thus breaking the authentication on redirect even when they specified -PreserveAuthorizationOnRedirect.

codewario
  • 19,553
  • 20
  • 90
  • 159
  • It's still giving me the 401 error even when I include the MaximumRedirection parameter and bump it up to 10 – JR_M Sep 01 '21 at 15:11
  • Sorry I removed the `-MaximumRedirection` piece, bad intel. But `-PreserveAuthorizationOnRedirect` is what you need. – codewario Sep 01 '21 at 15:13
  • It doesn't seem to work with that parameter either. – JR_M Sep 01 '21 at 16:43
  • 1
    After doing some deep digging into .NET Core's HttpWebRequest, I discovered that the PreAuthenticate property (which is what I think the PreserveAuthorizationOnRedirect is using) will only keep the authentication headers for requests made to a uri that includes the original uri up to the last "/". https://docs.microsoft.com/en-us/dotnet/api/system.net.httpwebrequest.preauthenticate?view=netcore-3.1 What the documentation doesn't include is that the subsequent uri's must also match the case of the original uri. The redirect switches a part of the uri to lowercase where the original has upper – JR_M Sep 02 '21 at 16:01
  • 1
    Ran out of space in the last comment. After changing the original uri to be lowercase, the PreserveAuthorizationOnRedirect is now working. Thank you for the help! – JR_M Sep 02 '21 at 16:03
  • Thanks for that additional info, I meant to come back to this but it slipped my mind. I'll add your new information to my answer. – codewario Sep 02 '21 at 17:05
  • It makes sense that the `Uri` is case-sensitive here, which is juxtaposed against PowerShell's (usually) case-insensitive nature. While some web servers are case-insensitive, this is not a reliable assumption to make and so server names and paths must be considered case-sensitive in `Uri`s if we are to assume the same identity and path. I'm sure there is an RFC somewhere which dictates this as well.. – codewario Sep 02 '21 at 17:15