使用来自 Windows 服务的 OpenID 连接通过 API 进行身份验证
Authenticate with API using OpenID connect from a Windows Service
我即将进行云迁移,我们之前在本地数据库之间传输数据方面做了很多工作。云提供商正在构建 API 以便我们在数据库进入云端后与它进行交互,所以我正在尝试编写一个 Windows 服务,该服务会定期从我们的其他服务器上吸取一些数据-prem db 和 post 它到云数据库。我无法弄清楚如何在 windows 服务中用 c# 实现 OpenID Connect 身份验证。我见过的所有示例都是 Web 应用程序。有人试过吗?
如果有人有比 windows 服务更好的主意,我愿意接受。
您应该寻找的是客户端凭据流(OpenID Connect 的一部分)。这是您在请求令牌时没有用户参与时使用的流程。
要获取令牌,您可以使用 IdentityModel 帮助程序库,您可以找到示例代码 here:
如果您不想使用 windows 服务,则另一种方法是创建一个控制台应用程序,您可以使用 windows 内置的任务调度程序来安排调用该应用程序。
或者,看看 HangFire.
我已与 API 通话。基本流程是您请求 Bearer 令牌,然后在相应的请求中传递令牌。这是我用来请求令牌的函数示例:
public static async Task<string> RequestTokenAsync()
{
var client = new HttpClient();
string token;
var con = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("client_id", "XXXXX"),
new KeyValuePair<string, string>("client_secret", "XXXXX"),
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "XXXXX"),
new KeyValuePair<string, string>("password", "XXXXX"),
new KeyValuePair<string, string>("device_id", "XXXXX"),
new KeyValuePair<string, string>("company", "XXXXX")
};
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://whatever/connect/token"),
Content = new FormUrlEncodedContent(con)
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded")
}
}
};
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
token = body;
}
}
catch (Exception ex)
{
return "ERROR: " + ex.Message;
}
Dictionary<string, object> values =
JsonConvert.DeserializeObject<Dictionary<string, object>>(token);
values.TryGetValue("access_token", out object extractedToken);
return extractedToken.ToString();
}
下面是使用令牌的示例:
public static async Task<List<Location>> GetLocations()
{
List<Location> result = new List<Location>();
string jsonResponse;
var client = new HttpClient();
string token = await RequestTokenAsync();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://whatever/v1/Locations"),
};
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + token);
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
jsonResponse = body.ToString();
try
{
result = JsonConvert.DeserializeObject<List<Location>>(jsonResponse);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
return result;
}
我即将进行云迁移,我们之前在本地数据库之间传输数据方面做了很多工作。云提供商正在构建 API 以便我们在数据库进入云端后与它进行交互,所以我正在尝试编写一个 Windows 服务,该服务会定期从我们的其他服务器上吸取一些数据-prem db 和 post 它到云数据库。我无法弄清楚如何在 windows 服务中用 c# 实现 OpenID Connect 身份验证。我见过的所有示例都是 Web 应用程序。有人试过吗?
如果有人有比 windows 服务更好的主意,我愿意接受。
您应该寻找的是客户端凭据流(OpenID Connect 的一部分)。这是您在请求令牌时没有用户参与时使用的流程。
要获取令牌,您可以使用 IdentityModel 帮助程序库,您可以找到示例代码 here:
如果您不想使用 windows 服务,则另一种方法是创建一个控制台应用程序,您可以使用 windows 内置的任务调度程序来安排调用该应用程序。 或者,看看 HangFire.
我已与 API 通话。基本流程是您请求 Bearer 令牌,然后在相应的请求中传递令牌。这是我用来请求令牌的函数示例:
public static async Task<string> RequestTokenAsync()
{
var client = new HttpClient();
string token;
var con = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("client_id", "XXXXX"),
new KeyValuePair<string, string>("client_secret", "XXXXX"),
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "XXXXX"),
new KeyValuePair<string, string>("password", "XXXXX"),
new KeyValuePair<string, string>("device_id", "XXXXX"),
new KeyValuePair<string, string>("company", "XXXXX")
};
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://whatever/connect/token"),
Content = new FormUrlEncodedContent(con)
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded")
}
}
};
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
token = body;
}
}
catch (Exception ex)
{
return "ERROR: " + ex.Message;
}
Dictionary<string, object> values =
JsonConvert.DeserializeObject<Dictionary<string, object>>(token);
values.TryGetValue("access_token", out object extractedToken);
return extractedToken.ToString();
}
下面是使用令牌的示例:
public static async Task<List<Location>> GetLocations()
{
List<Location> result = new List<Location>();
string jsonResponse;
var client = new HttpClient();
string token = await RequestTokenAsync();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://whatever/v1/Locations"),
};
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + token);
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
jsonResponse = body.ToString();
try
{
result = JsonConvert.DeserializeObject<List<Location>>(jsonResponse);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
return result;
}