我有一个.net(4.7.2或4.8)控制台应用程序,该应用程序使用HttpWebRequest来发布JWT样式身份验证数据以便检索JSON输出。我在Windows Server 2012盒子上遇到TLS 1.2站点的问题(在Windows 10上可以正常使用),并且建议我升级到HttpClient异步类。我正在努力寻找使用VB的HttpClient POST示例。...仅将代码转换为C#,用HttpClient异步POST代替HttpWebRequest会是什么样? HttpWebRequest的问题所在就是GetAccessToken方法。
任何帮助表示赞赏!
Imports System.Net
Imports System.IO
Imports System.Data.SqlClient
Imports System.Configuration
Imports Newtonsoft.Json.Linq
Imports System.Security.Cryptography
Module Module1
Public Class myAPIClass
'API info
Private API_ClientKey As String = ConfigurationManager.AppSettings("API_ClientKey")
Private API_ClientSecret As String = ConfigurationManager.AppSettings("API_ClientSecret")
Private FullURL As String = ConfigurationManager.AppSettings("URL")
'Quotation Mark Character for substitution
Private q As Char = Chr(34)
'JWT Claim Set Parameters
Property iss As String = API_ClientKey
Property aud As String = FullURL
Property AccessToken As String
Public Sub New()
GetAccessToken()
End Sub
Public Sub GetAccessToken()
System.Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12
Dim uriAddress As New Uri(FullURL)
Dim wRequest As HttpWebRequest = DirectCast(HttpWebRequest.Create(uriAddress), HttpWebRequest)
Dim strPostData As String = ""
Dim bytPostData As Byte()
Dim stJWT As String
'Get JWT
stJWT = CreateJWT()
'Post Data ---
strPostData = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer" & "&assertion=" & stJWT
'Post Data --- to byte()
bytPostData = System.Text.Encoding.UTF8.GetBytes(strPostData)
'Set Web Request Properties
With wRequest
.Method = "POST"
.ContentType = "application/x-www-form-urlencoded"
.ContentLength = bytPostData.Length
End With
'Post Request and Get Response
Using postStream As Stream = wRequest.GetRequestStream()
postStream.Write(bytPostData, 0, bytPostData.Length)
Dim rawResponseFromServer = ""
Try
Using response As HttpWebResponse = wRequest.GetResponse()
Dim reader As New StreamReader(response.GetResponseStream())
rawResponseFromServer = reader.ReadToEnd()
Dim o As JObject = JObject.Parse(rawResponseFromServer)
Me.AccessToken = o.Item("access_token").Value(Of String)()
End Using
Catch wex As WebException
If Not wex.Response Is Nothing Then
Console.WriteLine(wex.Message)
Console.WriteLine("Resulting Error --- " & wex.Message & vbNewLine & wex.StackTrace)
End If
End Try
End Using
End Sub
#Region "HelperFunctions"
Private Function CreateJWT() As String
Dim JWT As String
Dim EncodedJWT As Byte()
'Build Header and Claim Set String
Dim strHeader As String = Strings.Replace("{'alg':'HS256','typ':'JWT'}", "'", q)
Dim strClaimSet As String = Strings.Replace("{'iss':'" & iss & "', 'aud':'" & aud & "', 'exp':" & exp(600) & ", 'iat':" & iat() & "}", "'", q)
'Build JWT String
JWT = ToBase64URL(strHeader) & "." & ToBase64URL(strClaimSet)
'Convert Client Secret to UTF8 Byte()
Dim bytKey As Byte() = System.Text.Encoding.UTF8.GetBytes(API_ClientSecret)
'Encode JWT String
Dim hmac_encode As HMACSHA256 = New HMACSHA256(bytKey)
EncodedJWT = hmac_encode.ComputeHash(System.Text.Encoding.UTF8.GetBytes(JWT))
'Sign and return JWT
Dim signature As String = ToBase64URL(EncodedJWT)
Return JWT & "." & signature
End Function
Private Function ToBase64URL(Text As String) As String
Dim b As Byte() = System.Text.Encoding.UTF8.GetBytes(Text)
Return ToBase64URL(b)
End Function
Private Function ToBase64URL(byt As Byte()) As String
Dim result As String
'Convert to base 64 string
result = Convert.ToBase64String(byt)
'Make URL Friendly
result = result.Replace("+", "-").Replace("/", "_")
Do While result.Chars(result.Length - 1) = "="
result = Strings.Left(result, result.Length - 1)
Loop
Return result
End Function
ReadOnly Property exp(ExpirationSeconds As Integer) As Long
Get
Return iat() + ExpirationSeconds
End Get
End Property
ReadOnly Property iat() AsLong
Get
Dim StartDate As Date = CDate("1/1/1970")
Dim EndDate As Date = Now.ToUniversalTime
Dim val As Long = DateDiff(DateInterval.Second, StartDate, EndDate)
Return val
End Get
End Property
#End Region
End Class
Sub Main()
Console.WriteLine("Getting token...")
Dim myif As New myAPIClass()
Try
Console.WriteLine("Token received: " & myif.AccessToken)
Console.WriteLine("Connecting to SQL Server and inserting authentication token...")
Dim con As New SqlConnection(ConfigurationManager.AppSettings("ConnectionString"))
con.Open()
Dim cmd As New SqlCommand("INSERT INTO MYDB (InsertDate, AuthenticationCode, Length) VALUES ('" & DateTime.Now.ToString() & "', '" & myif.AccessToken & "', 40)", con)
cmd.ExecuteNonQuery()
Console.WriteLine("Done!")
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("Resulting Error --- " & ex.Message)
End Try
End Sub
End Module
答案 0 :(得分:0)
您的GetAccessToken方法应如下所示:
Public Sub GetAccessToken()
System.Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12
Dim tokenHttpClient As New HttpClient()
tokenHttpClient.BaseAddress = New Uri(FullURL)
Dim HttpRequestMessage As New HttpRequestMessage()
HttpRequestMessage.Method = HttpMethod.Post
HttpRequestMessage.Headers.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Dim stJWT As String = CreateJWT()
Dim parameters As New Dictionary(Of String, String)
parameters.Add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
parameters.Add("assertion", stJWT)
Dim encodedContent As New FormUrlEncodedContent(parameters)
encodedContent.Headers.ContentType = New MediaTypeHeaderValue("application/x-www-form-urlencoded")
HttpRequestMessage.Content = encodedContent
Dim response As HttpResponseMessage = tokenHttpClient.SendAsync(HttpRequestMessage).Result
If response.IsSuccessStatusCode Then
Dim rawResponseFromServer As String = response.Content.ReadAsStringAsync().Result
Dim o As JObject = JObject.Parse(rawResponseFromServer)
Me.AccessToken = o.Item("access_token").Value(Of String)()
End If
End Sub
请注意,httpClient中使用的所有功能都是异步的。.Result以同步方式强制它,而不必等待它们
我不确定它是否可以解决您的tls问题。您可能需要添加httpClientHandler
Dim httpClientHandler As New HttpClientHandler()
httpClientHandler.SslProtocols = Authentication.SslProtocols.Tls12 Or Authentication.SslProtocols.Tls11
httpClientHandler.ServerCertificateCustomValidationCallback = AddressOf TrustAllCertificatesCallback
tokenHttpClient = New HttpClient(httpClientHandler)
Private Function TrustAllCertificatesCallback(sender As Object, certificate As System.Security.Cryptography.X509Certificates.X509Certificate, chain As System.Security.Cryptography.X509Certificates.X509Chain, sslPolicyErrors As SslPolicyErrors) As Boolean
Return True
End Function
属性HttpClientHandler.SslProtocols可在Assembly System.Net.Http版本= 4.2.0.0中找到