2015-09-02 13 views
10

Tôi đang cố gắng liên lạc với một dịch vụ trên powerhell nhưng tôi thất bại thảm hại. Tôi nghi ngờ đó là giấy chứng nhận và tôi đã googled cho câu trả lời và tìm thấy hai lựa chọn, không ai trong số đó làm việc cho tôi. Tôi cũng đã cố gắng kết hợp cả hai không thành công.Powershell Invoke-RestMethod qua HTTPS

Lựa chọn 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" 

Phương án 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" 

Dưới đây là thông báo lỗi:

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 

tôi có thể thêm vào:

  • lướt trực tiếp đến dịch vụ làm việc với một trình duyệt web
  • Tôi đã cố gắng mở lòng với HTTP là tốt, và điều đó đã làm việc
  • Giấy chứng nhận sử dụng bởi các dịch vụ là tự ký nhưng đáng tin cậy bởi máy của tôi qua một root certficate (không có cảnh báo nào là vấn đề trong IE hoặc Chrome)
  • Tôi đã thực hiện chụp mạng và đảm bảo rằng một gói thực sự đến máy chủ.

Bất kỳ đề xuất nào được đánh giá cao!

Kind regards, Patrik

bài cập nhật như đề xuất của ông Tree dưới đây:

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    : 

Cập nhật 2 dựa trên một lời nhận xét của ông Tree:

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

Hãy thử '{$ true} -as [Net.Security.RemoteCertificateValidationCallback]' trong ví dụ thứ hai ... Bạn có cài đặt CA trong cửa hàng LocalMachine hoặc CurrentUser không? –

+0

Cảm ơn sự giúp đỡ của bạn. CA được cài đặt trong cả tài khoản CurrentUser và Computer của tôi trong Trusted Root Certification. Sẽ thêm kết quả của lệnh bạn đã đăng trong bài đăng của tôi ở trên. – PatrikJ

+0

(không chắc chắn những gì để tìm kiếm ở đó) – PatrikJ

Trả lời

20

Tôi giải quyết những bí ẩn trong khi xử lý sự cố điều khác. Máy chủ web được đề cập chỉ hỗ trợ TLS1.1 và TLS1.2. Powershell dường như KHÔNG hỗ trợ điều đó. Nếu tôi đã bật TLS1.0 thì nó hoạt động.

Để buộc TLS1.2 bạn có thể sử dụng dòng này:

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

Hy vọng giúp người khác và cảm ơn tất cả các nhận xét hữu ích!

/Patrik

+1

Giúp tôi một tấn. Cảm ơn vì đăng! – floyd

0

Nó xuất hiện bạn đang cố gắng gọi API json với Invoke-RestMethod. Theo documentation:

-ContentType

Chỉ định loại nội dung được yêu cầu web.

Nếu tham số này được bỏ đi và phương pháp yêu cầu là POST, Invoke-RestMethod đặt kiểu nội dung để "application/x-www-form-urlencoded". Nếu không, loại nội dung là không được chỉ định trong cuộc gọi.

Để sử dụng một cơ thể json, bạn sẽ cần phải sử dụng Invoke-RestMethod -ContentType 'application/json' <other args>

0

Tôi trải qua nhiều đau đớn gần đây để vượt qua một tình huống tương tự. Tôi đã tạo ra một bằng chứng về khái niệm sử dụng dịch vụ SaaS thử nghiệm. Dịch vụ này có chứng chỉ SSL tự ký vì vậy tôi muốn bỏ qua các lỗi chứng chỉ trong khi cố gắng gọi phương thức POST cho nó (tương tự như tham số "-k" cho curl). Sau nhiều cuộc đấu tranh, tôi thấy rằng cần cả hai - (a) cuộc gọi để bỏ qua các lỗi xác thực chứng chỉ và (b) cài đặt rõ ràng cho TLS 1.2 làm giao thức bảo mật. Tôi nghĩ rằng sau này bởi vì dịch vụ có lẽ đã giảm nỗ lực để kết nối bằng cách sử dụng bất kỳ giao thức nào khác. (Tôi đã dành quá nhiều thời gian cố gắng các biến thể khác nhau để thực hiện từng như đề xuất trên đề SOF khác nhau nhưng một cách độc lập ...)

Dưới đây là đoạn code mà làm việc ...

quan trọng: Các bypass xác nhận cert là hoàn toàn cho nguyên mẫu/PoC. Chúng tôi không có ý định làm điều này trong sản xuất (và bạn cũng không nên!).

$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 
} 

Cũng muốn thêm rằng các giao thức bảo mật ưa thích tiếp tục thay đổi khi các lỗ hổng khác được phát hiện và sửa lỗi được triển khai. Hơn nữa, các hệ thống khác nhau (các ngăn xếp SSL/TLS trong các hệ điều hành khách và các máy chủ/dịch vụ) thường có khả năng bắt kịp với các tùy chọn mới nhất/an toàn nhất. Vì vậy, chính xác cờ nào có thể hoạt động sẽ là một chức năng của hệ thống máy khách và máy chủ cũng như thời gian (trong đó TLS1.2 có thể không còn được ưa thích một vài tháng sau đó). Lý tưởng nhất là không cần phải chỉ định một lá cờ nào cả. Vui lòng xem phần "Ghi chú" trong this MSDN document để biết thêm.

Các vấn đề liên quan