根據博客園
solenovex的《
使用Identity Server 4建立Authorization Server》系列,老菜測試Asp.Net Core 2.0 WebAPI及IdentityServer4身份驗證 ,並實現客戶端訪問。
1、 打開VS2017,新建項目,選擇 .net core->ASP.NET Core Web應用程序,項目名稱為MyWebAPI,選擇WebAPI,完成項目創建。
2、工具菜單選擇Nuget包管理,打開“管理解決方案的NuGet包”,查找並安裝IdentityServer4和IdentityServer4.AccessTokenValida。
3、修改項目配置launchSettings.json:
{"profiles": {"MyWebAPI": {"commandName": "Project","launchBrowser": true,"environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"},"applicationUrl": "http://localhost:6000/"}}}
4、項目中建立Configuration目錄,建InMemoryConfiguration.cs:
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace MyWebAPI.Configuration
{
public class InMemoryConfiguration
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
public static IEnumerable<ApiResource> ApiResources()
{
return new[]
{
new ApiResource("socialnetwork", "社交網絡")
{
UserClaims = new [] { "email" }
}
};
}
public static IEnumerable<Client> Clients()
{
return new[]
{
new Client
{
ClientId = "socialnetwork",
ClientSecrets = new [] { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes = new [] { "socialnetwork" }
}
};
}
public static IEnumerable<TestUser> Users()
{
return new[]
{
new TestUser
{
SubjectId = "1",
Username = "mail@qq.com",
Password = "password",
Claims = new [] { new Claim("email", "mail@qq.com") }
}
};
}
}
}
5、 修改Startup.cs中的ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(InMemoryConfiguration.GetIdentityResources())
.AddTestUsers(InMemoryConfiguration.Users().ToList())
.AddInMemoryClients(InMemoryConfiguration.Clients())
.AddInMemoryApiResources(InMemoryConfiguration.ApiResources());
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.RequireHttpsMetadata = false;
options.Authority = "http://localhost:6000";
options.ApiName = "socialnetwork";
});
}
6、修改Startup.cs中的Configure
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
7、修改示例API控制器——ValuesController
[Authorize]
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public JsonResult Get()
{
JsonResult a = new JsonResult(new string[]{ "value1", "value2" });
return a;
}
}
8、運行項目,彈出dotnet console窗體,並在項目根目錄生成臨時證書tempkey.rsa
9、運行Postman,在builder中創建POST標簽窗口,POST測試獲取token


即可獲得token。
10、客戶端之一(IdentityModel): 新建.net Core 2 console控制台應用項目MyClient。通過“管理解決方案的NuGet包”,查找並安裝IdentityModel包。 代碼如下:
using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace MyClient
{
class Program
{
public static void Main(string[] args) => MainAsync().GetAwaiter().GetResult();
private static async Task MainAsync()
{
//DiscoveryClient類:IdentityModel提供給我們通過基礎地址(如:http://localhost:6000)
//就可以訪問令牌服務端;當然可以根據上面的restful api里面的url自行構建;上面就是通過基礎地址,
//獲取一個TokenClient;(對應restful的url:token_endpoint= "http://localhost:6000/connect/token")
var dico = await DiscoveryClient.GetAsync("http://localhost:6000");
//token
var tokenClient = new TokenClient(dico.TokenEndpoint, "socialnetwork", "secret");
var tokenresp = await tokenClient.RequestClientCredentialsAsync("socialnetwork");
if (tokenresp.IsError)
{
Console.WriteLine(tokenresp.Error);
return;
}
Console.WriteLine(tokenresp.Json);
Console.WriteLine("\n\n");
var client = new HttpClient();
client.SetBearerToken(tokenresp.AccessToken);
var resp = await client.GetAsync("http://localhost:6000/api/values");
//var resp = await client.GetAsync("http://localhost:6000/identity");
if (!resp.IsSuccessStatusCode)
{
Console.WriteLine(resp.StatusCode);
}
else
{
var content = await resp.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
Console.ReadKey(true);
}
}
}
結果:

11、客戶端之一(Restsharp),另外新建.net Core 2 console控制台應用項目MyjwtClient。通過“管理解決方案的NuGet包”,查找並安裝Restsharp、Newtonsoft.Json包。 代碼如下:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using RestSharp.Authenticators;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyClient
{
class Program
{
/// <summary>
/// 訪問Url
/// </summary>
static string _url = "http://localhost:6000";
static void Main(string[] args)
{
var client = new RestClient(_url);
RestRequest request = CreatePostTokenRestRequest(client);
var response = client.Execute(request);
JObject jo = (JObject)JsonConvert.DeserializeObject(response.Content);
Console.WriteLine(response.Content);
string access_token = jo["access_token"].ToString();
RestRequest requestapi = CreateGetApiRestRequestByToken(access_token);
var responseapi = client.Execute(requestapi);
Console.WriteLine(responseapi.Content);
Console.ReadKey(true);
}
private static RestRequest CreateGetApiRestRequestByToken(string access_token)
{
RestRequest requestapi = new RestRequest() { Method = Method.GET };
requestapi.AddHeader("Content-Type", "application/x-www-form-urlencoded");
requestapi.AddHeader("Accept", "application/json");
requestapi.AddHeader("authorization", string.Format("Bearer {0}", access_token));
requestapi.Resource = "/api/values";
return requestapi;
}
private static RestRequest CreatePostTokenRestRequest(RestClient client)
{
RestRequest request = new RestRequest() { Method = Method.POST };
client.Authenticator = new HttpBasicAuthenticator("socialnetwork", "secret");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Accept", "application/json");
request.AddParameter("client_id", "socialnetwork");
request.AddParameter("client_secret", "secret");
request.AddParameter("grant_type", "password");
request.AddParameter("username", "mail@qq.com");
request.AddParameter("password", "password");
request.Resource = "/connect/token";
return request;
}
private static RestRequest CreatePostRefresfTokenRestRequest(RestClient client)
{
RestRequest request = new RestRequest() { Method = Method.POST };
client.Authenticator = new HttpBasicAuthenticator("socialnetwork", "secret");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Accept", "application/json");
request.AddParameter("client_id", "mvc_code");
request.AddParameter("client_secret", "secret");
request.AddParameter("grant_type", "hybird");
request.AddParameter("username", "mail@qq.com");
request.AddParameter("password", "password");
request.Resource = "/connect/token";
return request;
}
}
}
12、先運行MyWebApi,后運行MyClient

在MyClient中通過RestRequest獲取response,通過JsonConvert.DeserializeObject解析response內容中的access_token,然后通過創建WebAPI請求的RestRequest,根據access_token,獲得webapi的返回值。