根据博客园
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的返回值。