0 官方文档 https://identityserver4.readthedocs.io/en/latest/
1 IdentityServer4 ASP .NET Core 认证中心 搭建
1.1 新建ASP .NET Core 项目 nuget IdentityServer4
1.2 新建配置类 IdentityConfig 代码如下 :
public class IdentityConfig
{
/// <summary>
/// ApiResource
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetResource()
{
return new List<ApiResource>() {
new ApiResource("UserAPI","OrderAPI"){
} };
}
/// <summary>
/// Client
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
var cilentApp = new Client()
{
ClientId = "App1",
ClientName = "App",
AllowedGrantTypes = new List<string>() {
GrantType.ClientCredentials },
ClientSecrets = new List<Secret>() {
new Secret("Sercrect".Sha256())
},
AllowedScopes = { "UserAPI"}
};
return new List<Client>() {
cilentApp
};
}
}
1.3 Startup.cs配置 IdentityServer 代码如下
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//依赖注入系统中注册IdentityServer
services.AddIdentityServer()
//扩展在每次启动时,为令牌签名创建了一个临时密钥。在生成环境需要一个持久化的密钥
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(IdentityConfig.GetResource())//Api 资源
.AddInMemoryClients(IdentityConfig.GetClients());//Api的客户端
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseIdentityServer();//使用服务 中间件被添加到HTTP管道中
}
1.4 启动站点 输入 http://localhost:4000/.well-known/openid-configuration
,可以看到授权的终结点等信息。
222.png
1.5 获取Token
POST 传入 client_id 分配的客户端ID,client_secret 分配的客户端密钥,
grant_type 为认证类型。
模拟POST请求获取token(1.4中的终结点信息中token_endpoint ) ,请求信息如下:
```
POST /connect/token HTTP/1.1
Host: localhost:4000
Cache-Control: no-cache
Postman-Token: 63d697a1-c044-5f2e-0824-e16c1ed466ce
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="client_id"
App1
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="client_secret"
Secret
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="grant_type"
client_credentials
------WebKitFormBoundary7MA4YWxkTrZu0gW--
```
示例JSON
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImUyM2FkOWMxZmQwZjJjMDU2YTVlN2I3MzU1OWU5MDY1IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NDQ0MzA3NTAsImV4cCI6MTU0NDQzNDM1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9yZXNvdXJjZXMiLCJVc2VyQVBJIl0sImNsaWVudF9pZCI6IkFwcDEiLCJzY29wZSI6WyJVc2VyQVBJIl19.dyCNlu2ModdXijNYb9kpEPREp1vXxTJrQLjKJrd40PtqnXmHhtgVyg_ynZ4rpytpFFTyw2t9Q-DZqbNGU4FiZsGvbUzq2js87qbMeWinHsFcvjOpVP-PPN12XCiHR7uMcaWIlksgdaOyzn9rGip49Y2qB9EcAQ10a282FtiAd3r-rUaTnEwu2uHZhCaTgcYeuWAgKjslBTR-dmQEM-8QonUK0mCIybiwx2XUNddL4EeYyNUnJnJiC4SmeJwhJGpR-Ayh3S-Kg_IjFiRZTnKfkQEpZcEzbyxf_LAlCIUrEx1OKeZizOsl10h4VyS-5LB-64bISCbLQZFunGHc0shkXw",
"expires_in": 3600,
"token_type": "Bearer"
}
access_token为token 信息,用于访问信息
1.6 使用Identity 保护API
新建ASP .NET Core WebAPI项目IdentityServer.UserAPI,
NUGET 安装 IdentityServer4.AccessTokenValidation
。
在默认的 ValuesController 控制器加上特性标签 Authorize
.
代码如下:
[Route("api/[controller]")]
[Authorize]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
}
然后在Startup.cs
中配置IdentityServer,如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(c => {
c.Authority = "http://localhost:4000";//授权服务器地址
c.RequireHttpsMetadata = false;
c.ApiName = "UserAPI";//API 名称
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();//开启授权
app.UseMvc();
}
以上配置完成,启动IdentityServer.UserAPI,访问http://localhost:4001/api/values,会返回401状态,未授权。
使用1.5中的Token来访问API,
在HTTP请求报文的Head 信息中加入 Authorization头,值为 Bearer 空格 加上 token。
HTTP信息如下:
GET /api/values HTTP/1.1
Host: localhost:4001
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImUyM2FkOWMxZmQwZjJjMDU2YTVlN2I3MzU1OWU5MDY1IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NDQ0MzA3NTAsImV4cCI6MTU0NDQzNDM1MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9yZXNvdXJjZXMiLCJVc2VyQVBJIl0sImNsaWVudF9pZCI6IkFwcDEiLCJzY29wZSI6WyJVc2VyQVBJIl19.dyCNlu2ModdXijNYb9kpEPREp1vXxTJrQLjKJrd40PtqnXmHhtgVyg_ynZ4rpytpFFTyw2t9Q-DZqbNGU4FiZsGvbUzq2js87qbMeWinHsFcvjOpVP-PPN12XCiHR7uMcaWIlksgdaOyzn9rGip49Y2qB9EcAQ10a282FtiAd3r-rUaTnEwu2uHZhCaTgcYeuWAgKjslBTR-dmQEM-8QonUK0mCIybiwx2XUNddL4EeYyNUnJnJiC4SmeJwhJGpR-Ayh3S-Kg_IjFiRZTnKfkQEpZcEzbyxf_LAlCIUrEx1OKeZizOsl10h4VyS-5LB-64bISCbLQZFunGHc0shkXw
Cache-Control: no-cache
Postman-Token: 57b580b9-3a85-23ad-6469-41763bc5da05
可以看到正常API的返回。
1.7 C# 调用API
步骤为
1 创建Core Cmd 项目 NUGET 安装IdentityModel
.
2 创建授权服务发现实例
3 创建授权token 获取Client 获取token
4 HttpClient实例用token 调用API
代码如下:
using System;
using System.Net.Http;
using IdentityModel;
using IdentityModel.Client;
namespace IdentityServer.UseCmd
{
class Program
{
static void Main(string[] args)
{
//1.1 授权服务发现
var disco=DiscoveryClient.GetAsync("http://localhost:4000").Result;
if (disco.IsError)
{
Console.WriteLine(disco.Error);
Console.ReadLine();
return;
}
//1.2 获取token
var tokenClient = new TokenClient
(
//授权 获取token 节点
disco.TokenEndpoint,
//ClientId
"App1",
//ClientSecret
"Secret");
var tokenResponse = tokenClient.RequestClientCredentialsAsync().Result;
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
//1.3 调用API
HttpClient c = new HttpClient();
//设置授权信息
c.SetBearerToken(tokenResponse.AccessToken);
var jsonRe = c.GetAsync("http://localhost:4001/api/values").Result;
Console.WriteLine(jsonRe.Content.ReadAsStringAsync().Result);
Console.ReadLine();
}
}
}
参考文档:https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html
网友评论