You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Windows Service向ABP Framework API发送请求失败问题

问题:Windows Service调用ABP Framework OAuth2授权API失败

我需要开发一个Windows Service,向ABP Framework的API发送数据。该API采用OAuth2授权验证,需登录后才能访问。我先开发了控制台应用,能正常完成登录并调用API;但使用nssm.exe将其转为Windows Service后,无法正常运行。我认为这和Windows Service的访问限制有关。

1) ConsoleServerApplication代码

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 Service没有界面,且通过它打开应用并非最佳实践,我创建了3个辅助应用用于获取令牌所需的CODE:

  • 获取CODE需要先完成登录,授权成功后会收到包含CODE的跳转链接
  • 我通过网页抓取从链接中提取CODE,再发送至ConsoleServerApplication

有没有人知道如何解决这个问题?


内容的提问来源于stack exchange,提问作者Egor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:54:53