我们正在使用身份服务器为我们的网络服务生成访问令牌。我们还添加了招摇。 但我们面临的问题是,通过 API 自动化的代码片段生成访问令牌。 是否有任何使用用户名和密码自动获取访问令牌的方法?
我解决这个问题的方法是,如果配置了测试客户端密钥,则添加客户端凭据客户端,我仅在测试环境中配置此密钥,但显然不在更高的环境中,这意味着客户端永远不会添加到那里。
因此,无论是在您的 appsettings.{property_environment}.settings 中还是通过环境变量设置客户端密钥,然后在您的 IdentityServer 配置中您可以添加:
//attempt to get the test client secret
var testClientSecret = configuration["TestClientSecret"];
if (!String.IsNullOrWhiteSpace(testClientSecret))
{
clients.Add(new Client
{
ClientId = "MyTestClient",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret(testClientSecret.Sha256())
},
AllowedScopes = { "MyApiScope", "MyOtherApiScope", "etc." }
});
};
然后我有一个 Postman 测试集合,首先发布到:
https://{{idp_base_url}}/connect/token
使用基本身份验证以及测试客户端名称的用户名和密码作为客户端密钥(其中 {{idp_base_url}} 是包含适合环境的 IdentityServer 主机的 postman 环境变量)。
然后我运行一些测试,同时还将访问令牌存储到 API:
//tests...
var tokenData = JSON.parse(responseBody);
//more tests...
postman.setEnvironmentVariable("cc_token", tokenData.access_token);
集合中的后续测试可以使用此令牌以及使用上面的 Postman 环境变量的不记名令牌身份验证标头来运行 API 测试:
另一种方法是使用
IdentityModel
NuGet 获取令牌。示例:
var client = new HttpClient();
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = $"{IdentityServerUrl}/connect/token",
ClientId = "THE_CLIENT_ID",
ClientSecret = IdentityServerPass,
Scope = "api.read"
}).ConfigureAwait(false);
tokenResponse.HttpResponse.EnsureSuccessStatusCode();
首先声明一个名为Token的类。
public class Token
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("userName")]
public string Username { get; set; }
[JsonProperty(".issued")]
public string IssuedAt { get; set; }
[JsonProperty(".expires")]
public string ExpiresAt { get; set; }
}
在Postman中,我们在POST方法中使用用户名、密码和grant_type从baseURl/token uri生成access_token。要了解您应该使用什么 url,请检查 App_Start 文件夹中的 Startup.Auth.cs 文件。
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
.....
}
适当的 URL 由 PathString() 构造函数内的字符串确定。
一旦知道要调用的 url,现在要获取访问令牌,请考虑以下代码。
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password",password),
new KeyValuePair<string, string>("grant_type", "password")
};
var request = new HttpRequestMessage(HttpMethod.Post, "baseUrl/Token");
request.Content = new FormUrlEncodedContent(keyValues);
var client = new HttpClient();
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
var accessTokenVar = JsonConvert.DeserializeObject<AuthenticationToken>(content);
现在可以使用 accessTokenVar 访问访问令牌。