我正在尝试创建一个将数据发送到 ABP 框架 API 的 Windows 服务。 我了解到,要访问 API,您需要登录。 在 ABP 框架中,授权使用 OAuth 2 进行。 我创建了一个控制台应用程序,用于登录并向 API 发送数据,一切正常,然后我使用 nmss.exe 从我的控制台应用程序创建 Windows 服务,但不幸的是这不起作用。
1) 控制台服务器应用程序
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using RestSharp.Authenticators.OAuth2;
using System.Net;
using System.Text;
namespace NewServerProject
{
public class Program
{
static async Task Main(string[] args)
{
using var listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8001/");
listener.Start();
while (true)
{
var context = listener.GetContext();
var request = context.Request;
if (request.HttpMethod == "POST")
{
await PostRequestFromGate(request, context);
context.Response.Close();
}
}
}
static async Task PostRequestFromGate(HttpListenerRequest request, HttpListenerContext context)
{
string text;
using (var reader = new StreamReader(request.InputStream,
request.ContentEncoding))
{
text = reader.ReadToEnd();
}
await PostRequestToAPI(text);
}
static async Task PostRequestToAPI(string text)
{
string clientId = "CM_Postman";
string clientSecret = "3284687Egor";
string redirectUri = "https://localhost:44318/swagger/oauth2-redirect.html";
string authorizationEndpoint = "https://localhost:44350/connect/authorize";
string scope = "TestProject";
string tokenEndpoint = "https://localhost:44350/connect/token";
string authorizationCode = GetAuthorizationCode(authorizationEndpoint, clientId, redirectUri, scope);
string accessTokfen = GetAuthToken(tokenEndpoint, clientId, clientSecret, authorizationCode, redirectUri);
await GetData(accessTokfen, text);
}
static string GetAuthorizationCode(string authorizationEndpoint, string clientId, string redirectUri, string scope)
{
string authorizationUrl = $"{authorizationEndpoint}?client_id={clientId}&redirect_uri={redirectUri}&scope={scope}&response_type=code";
return PostToSupportApp(authorizationUrl).Result;
}
public record JsonClass(string url);
static async Task<string> PostToSupportApp(string url)
{
JsonClass jsonClass = new(url);
string jsonString = JsonConvert.SerializeObject(jsonClass);
var client = new RestClient("http://localhost:8003/");
var request = new RestRequest()
{
Method = Method.Post
};
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddParameter("application/json", jsonString, ParameterType.RequestBody);
RestResponse response = client.Execute(request);
foreach (var f in response.Headers)
{
if (f.Name.ToString() == "code")
{
return f.Value.ToString();
}
}
return null;
}
public record Token(string access_token, string token_type, int expires_in, string scope);
static string GetAuthToken(string tokenEndpoint, string clientId,
string clientSecret, string authorizationCode, string redirectUri)
{
var client = new RestClient(tokenEndpoint);
var request = new RestRequest()
{
Method = Method.Post
};
request.AddParameter("grant_type", "authorization_code");
request.AddParameter("code", authorizationCode);
request.AddParameter("redirect_uri", redirectUri);
request.AddParameter("username", "admin");
request.AddParameter("password", "1q2w3E*");
request.AddParameter("client_id", clientId);
request.AddParameter("client_secret", clientSecret);
RestResponse response = client.Execute(request);
Token token = System.Text.Json.JsonSerializer.Deserialize<Token>(response.Content.ToString());
// Extract and return the access token
return token.access_token;
}
static async Task GetData(string accesToken, string jsodata)
{
string apiEndpoint = "https://localhost:44318/api/app/check-ins/datanew";
var authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(
accesToken, "Bearer"
);
var options = new RestClientOptions(apiEndpoint)
{
Authenticator = authenticator
};
var client = new RestClient(options);
var request = new RestRequest()
{
Method = Method.Post
};
request.AddJsonBody(jsodata);
RestResponse response = client.Execute(request);
}
}
}
2)SupportConsoleApp(由于Windows服务没有接口,使用它打开应用程序不是一个好习惯,我创建了3个应用程序,它们将在将来接收“CODE”以获取令牌) 要接收代码,您必须首先登录,成功授权后,我们会在“代码”所在的链接中收到重定向,并使用网页抓取将其从链接中提取出来并将其发送到 ConsoleServerApplication。
有谁知道如何解决这个问题吗? 我认为这与限制对 Windows 服务的访问有关
我的问题是,由于某种原因,Windows 服务由于 SSL 证书而不想授予对应用程序的访问权限,因此我在互联网上搜索了几天,找到了一个对我有帮助的解决方案
using (HttpClient client = new HttpClient(new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (a, b, c, d) => true
}))
我在发送请求时禁用证书并且它有效。