2015-09-02 16 views
10

Próbuję komunikować się z usługą za pomocą programu Power Shell, ale ponoszę porażkę. Podejrzewam, że jest to zaświadczenie, a ja szukałem odpowiedzi i znalazłem dwie opcje, z których żadna nie zadziałała. Próbowałem też połączyć oba bezskutecznie.Powershell Invoke-RestMethod za pośrednictwem protokołu HTTPS

Wariant 1:

add-type @" 
    using System.Net; 
    using System.Security.Cryptography.X509Certificates; 
    public class TrustAllCertsPolicy : ICertificatePolicy { 
     public bool CheckValidationResult(
      ServicePoint srvPoint, X509Certificate certificate, 
      WebRequest request, int certificateProblem) { 
      return true; 
     } 
    } 
"@ 
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 

$urlJSON = "https://internal.ad.local/path/api_jsonrpc.php" 

#Create authentication JSON object using ConvertTo-JSON 
$objAuth = (New-Object PSObject | Add-Member -PassThru NoteProperty jsonrpc '2.0' | 
Add-Member -PassThru NoteProperty method 'user.authenticate' | 
Add-Member -PassThru NoteProperty params @{user="user";password="password"} | 
Add-Member -PassThru NoteProperty id '2') | ConvertTo-Json 


Invoke-RestMethod -Uri $urlJSON -body $objAuth -method "Post" 

Opcja 2:

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} 

$urlJSON = "https://internal.ad.local/path/api_jsonrpc.php" 

#Create authentication JSON object using ConvertTo-JSON 
$objAuth = (New-Object PSObject | Add-Member -PassThru NoteProperty jsonrpc '2.0' | 
Add-Member -PassThru NoteProperty method 'user.authenticate' | 
Add-Member -PassThru NoteProperty params @{user="user";password="password"} | 
Add-Member -PassThru NoteProperty id '2') | ConvertTo-Json 


Invoke-RestMethod -Uri $urlJSON -body $objAuth -method "Post" 

Oto komunikat błędu:

Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send. 
At C:\Users\user\AppData\Local\Temp\46eaa6f7-62a0-4c10-88d1-79212d652bc9.ps1:24 char:1 
+ Invoke-RestMethod -Uri $urlJSON -body $objAuth -method "Post" 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException 
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand 

dodam:

  • surfowanie bezpośrednio do serwisu działa z przeglądarką internetową
  • Próbowałem otwarcie na HTTP jako dobrze, i że pracował
  • Certyfikat użyty przez usługę jest autopodpisywany ale ufa moim komputerze za pośrednictwem certyfikat root (brak ostrzeżeń to problemy w IE lub Chrome)
  • Dokonałem przechwycenia sieci i upewniłem się, że pakiety rzeczywiście docierają do serwera.

Wszelkie sugestie doceniane!

pozdrowienia rodzaju, Patrik

Updated po co do propozycji przedstawionych przez pana Drzewa poniżej:

Name      : lambda_method 
DeclaringType    : 
ReflectedType    : 
Module      : RefEmit_InMemoryManifestModule 
MethodHandle    : 
Attributes     : PrivateScope, Public, Static 
CallingConvention   : Standard 
IsSecurityCritical   : False 
IsSecuritySafeCritical  : False 
IsSecurityTransparent  : True 
ReturnType     : System.Boolean 
ReturnParameter   : 
ReturnTypeCustomAttributes : System.Reflection.Emit.DynamicMethod+RTDynamicMethod+EmptyCAHolder 
MemberType     : Method 
MethodImplementationFlags : NoInlining 
IsGenericMethodDefinition : False 
ContainsGenericParameters : False 
IsGenericMethod   : False 
IsPublic     : True 
IsPrivate     : False 
IsFamily     : False 
IsAssembly     : False 
IsFamilyAndAssembly  : False 
IsFamilyOrAssembly   : False 
IsStatic     : True 
IsFinal     : False 
IsVirtual     : False 
IsHideBySig    : False 
IsAbstract     : False 
IsSpecialName    : False 
IsConstructor    : False 
CustomAttributes   : 
MetadataToken    : 

Update 2 w oparciu o komentarz przez pana Drzewo: To wydaje

Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send. 
At C:\Users\user\AppData\Local\Temp\ff47910e-fd8e-4be8-9241-99322144976a.ps1:13 char:1 
+ Invoke-RestMethod -Uri $urlJSON -body $objAuth -method "Post" 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException 
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand 
+1

Spróbuj '{$ true} -as [Net.Security.RemoteCertificateValidationCallback]' w drugim przykładzie ... Czy masz zainstalowany urząd certyfikacji w sklepie LocalMachine lub CurrentUser? –

+0

Dziękuję za pomoc. CA jest zainstalowany pod kontem Moje bieżące konto i Komputer w Zaufanej certyfikacji głównej. Doda wynik polecenia, które opublikowałeś w moim poście powyżej. – PatrikJ

+0

(nie wiesz, czego szukać) – PatrikJ

Odpowiedz

20

I rozwiązać tajemnicę podczas rozwiązywania coś innego. Dany serwer WWW obsługuje tylko TLS1.1 i TLS1.2. Powershell wcale tego nie obsługuje. Jeśli włączono TLS1.0, zadziałało.

Aby wymusić TLS1.2 możesz użyć tej linii:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 

Mam nadzieję, że pomaga komuś innemu i dzięki za wszystkie pomocne komentarze!

/Patrik

+1

Pomógł mi tonę. Dzięki za publikację! – floyd

0

próbujesz wywołać json API z Invoke-RestMethod. Według documentation:

-ContentType

Określa typ zawartości wniosku internetowej.

Jeśli parametr ten jest pomijany, a wniosek jest sposób PO, Wywołanie-RestMethod określa typ zawartości "application/x-www postać urlencoded". W przeciwnym razie typ zawartości nie jest określony w wywołaniu.

Aby użyć json ciało, trzeba będzie użyć Invoke-RestMethod -ContentType 'application/json' <other args>

0

Przeszedłem przez wiele bólu niedawno, aby ominąć podobnej sytuacji. Stworzyłem proof of concept przy użyciu próbnej usługi SaaS. Usługa posiadała samopodpisany certyfikat SSL, więc chciałem zignorować błędy certyfikatu podczas próby wywołania metody POST (podobnie do parametru "-k" dla zwijania). Po wielu zmaganiach odkryłem, że potrzebne jest wywołanie zignorowania błędów sprawdzania poprawności certyfikatu i (b) jednoznaczne ustawienie TLS 1.2 jako protokołu bezpieczeństwa. Myślę, że to drugie, ponieważ usługa prawdopodobnie pogarszała próby połączenia przy użyciu dowolnego z pozostałych protokołów. (Spędziłem zbyt wiele czasu próbując różnych wariantów dla każdego robi jak sugerowano na różnych SOF wątków Niezależnie jednak ...)

Oto kod, który pracował ...

Ważne: Obwodnica jest walidacja cert wyłącznie dla prototypu/PoC. Nie zamierzamy tego robić w produkcji (i ty też nie powinieneś!).

$defaultSecurityProtocol = $null 
try 
{ 
    #BUGBUG, TODO: Disabling cert validation for the duration of this call...('trial' version cert is self-signed.) 
    #Remove this after the PoC. 
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } 
    #Cache the previous protocol setting and explicitly require TLS 1.2 
    $defaultSecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol 
    [System.Net.ServicePointManager]::SecurityProtocol = ` 
       [System.Net.SecurityProtocolType]::Tls12 

    if (-not [String]::IsNullOrWhiteSpace($authZHeaderValue)) 
    { 
     $response = Invoke-WebRequest ` 
        -Uri $webhookUrl ` 
        -Method "Post" ` 
        -Body $eventJson ` 
        -Header @{ $authZHeaderName = $authZHeaderValue} 
    } 
    else 
    { 
     $response = Invoke-WebRequest ` 
        -Uri $webhookUrl ` 
        -Method "Post" ` 
        -Body $eventJson 
    } 
} 
catch 
{ 
    $msg = $_.Exception.Message 
    $status = $_.Exception.Status 
    $hr = "{0:x8}" -f ($_.Exception.HResult) 
    $innerException = $_.Exception.InnerException 
    #Just issue a warning about being unable to send the notification... 
    Write-Warning("`n`t[$status] `n`t[0x$hr] `n`t[$msg] `n`t[$innerException]") 
} 
finally 
{ 
    # Set securityProtocol and CertValidation behavior back to the previous state. 
    [System.Net.ServicePointManager]::SecurityProtocol = $defaultSecurityProtocol 
     [System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null 
} 

Należy również dodać, że preferowane protokoły bezpieczeństwa zmieniają się wraz z wykryciem różnych luk i zaimplementowanymi poprawkami. Co więcej, różne systemy (stosy SSL/TLS w systemach operacyjnych klienta i serwerach/usługach) często mają własne zaległości w korzystaniu z najnowszych/najbezpieczniejszych opcji. Zatem dokładnie to, która flaga może działać, będzie funkcją systemu klienta i serwera, a także czasu (w tym, że TLS1.2 może nie pozostać preferowanym kilka miesięcy później). Idealnie nie powinno się w ogóle określać flagi. Więcej informacji można znaleźć w sekcji "Uwagi" w numerze this MSDN document.

Powiązane problemy