.net core 用 identitymodel 请求token。
identitymodel 也有在Nuget里搜索和安装。
identitymodel 扩展了HttpClient的一些方法用于token请求。
例如:client.RequestTokenAsync(new TokenRequest)
Token Endpoint
The client library for the token endpoint (OAuth 2.0 and OpenID Connect) is provided as a set of extension methods for HttpClient
. This allows creating and managing the lifetime of the HttpClient
the way you prefer - e.g. statically or via a factory like the Microsoft HttpClientFactory
.
Requesting a token
The main extension method is called RequestTokenAsync
- it has direct support for standard parameters like client ID/secret (or assertion) and grant type, but it also allows setting arbitrary other parameters via a dictionary. All other extensions methods ultimately call this method internally:
var client = new HttpClient();
var response = await client.RequestTokenAsync(new TokenRequest
{
Address = "https://demo.identityserver.io/connect/token",
GrantType = "custom",
ClientId = "client",
ClientSecret = "secret",
Parameters =
{
{ "custom_parameter", "custom value"},
{ "scope", "api1" }
}
});
The response is of type TokenResponse
and has properties for the standard token response parameters like access_token
, expires_in
etc. You also have access to the the raw response as well as to a parsed JSON document (via the Raw
and Json
properties).
Before using the response, you should always check the IsError
property to make sure the request was successful:
if (response.IsError) throw new Exception(response.Error);
var token = response.AccessToken;
var custom = response.Json.TryGetString("custom_parameter");
Requesting a token using the client_credentials
Grant Type
The RequestClientCredentialsToken
extension method has convenience properties for the client_credentials
grant type:
var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = "https://demo.identityserver.io/connect/token",
ClientId = "client",
ClientSecret = "secret",
Scope = "api1"
});
Requesting a token using the password
Grant Type
The RequestPasswordToken
extension method has convenience properties for the password
grant type:
var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = "https://demo.identityserver.io/connect/token",
ClientId = "client",
ClientSecret = "secret",
Scope = "api1",
UserName = "bob",
Password = "bob"
});
Requesting a token using the refresh_token
Grant Type
The RequestRefreshToken
extension method has convenience properties for the refresh_token
grant type:
var response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
RefreshToken = "xyz"
});
Requesting a Device Token
The RequestDeviceToken
extension method has convenience properties for the urn:ietf:params:oauth:grant-type:device_code
grant type:
var response = await client.RequestDeviceTokenAsync(new DeviceTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "device",
DeviceCode = authorizeResponse.DeviceCode
});
参考:https://identitymodel.readthedocs.io/en/latest/client/token.html
例子code:
using System; using System.Net.Http; using IdentityModel.Client; namespace ClientCredential { class Program { static void Main(string[] args) { try { new Program().GetAsync(); } catch (Exception ex) { System.Console.WriteLine(ex.Message); } Console.ReadKey(); } public async void GetAsync() { var diso = await DiscoveryClient.GetAsync("http://localhost:5003"); if (diso.IsError) { System.Console.WriteLine("diso.Error"); } var tokenClient = new TokenClient(diso.TokenEndpoint, "client", "secrt"); var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api"); if (tokenResponse.IsError) { System.Console.WriteLine(tokenResponse.Error); } else { System.Console.WriteLine(tokenResponse.Json); } using (var httpClient = new HttpClient()) { httpClient.SetBearerToken(tokenResponse.AccessToken); var response = await httpClient.GetAsync("http://localhost:5001/api/values"); if (response.IsSuccessStatusCode) { System.Console.WriteLine(await response.Content.ReadAsStringAsync()); } } } } }