一、介绍定义
1. 参考官网和百度
Core 2文档http://docs.identityserver.io/en/aspnetcore2/endpoints/token.html
Core 3+文档https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html
二、开始创建IdentityServer4服务
1. 创建解决方案、项目
2. 添加NuGet包:“IdentityServer4”
3. 添加配置类“IdentityServerConfig.cs”
public static class IdentityServerConfig
{
}
4. ApiResource、ApiScope
需要注意core2为定义资源,core3+为定义范围
//asp.net Core 2
public static IEnumerable<ApiResource> GetApis=>
new List<ApiResource>
{
new ApiResource("api1", "My API")
};
//asp.net Core 3+
public static IEnumerable<ApiScope> ApiScopes =>
new List<ApiScope>
{
new ApiScope("api1", "My API")
};
5. 定义client
/// <summary>
/// 配置客户端
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client{
ClientId = "clientId",
ClientSecrets={ new Secret ("clientSecrets".Sha256()) },
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes = { "api1" }
},
};
6. 配置服务
services.AddIdentityServer()
.AddDeveloperSigningCredential()
//.AddInMemoryApiResources(IdentityServerConfig.GetApis) //.net Core 2 用这个
.AddInMemoryApiScopes(IdentityServerConfig.ApiScopes) //.net Core 3+ 用这个
.AddInMemoryClients(IdentityServerConfig.Clients)
//.AddTestUsers(IdentityServerConfig.Users);
7. 如果使用用户模式:配置用户信息(不推荐使用用户模式)
//此处使用用户仓储、DAL,等使用数据的用户信息
public static List<TestUser> Users =>
new List<TestUser>
{
new TestUser {SubjectId = "1",Username = "alice",Password = "password"},
new TestUser {SubjectId = "2",Username = "bob",Password = "password"}
};
8. 处理管道,添加中间件
// Configure方法中添加,并且添加在UseRouting中间件之前
app.UseIdentityServer();
9. 运行调试。
http://localhost:5001/.well-known/openid-configuration 发现文档地址
选中部分为获取token的地址
// 客户端参数:必填
client_id clientId
client_secret clientSecrets
//用户密码参数 用户方式必填
username alice
password password
//认证方式 必填,对应“第5步中的GrantTypes属性”,4种方式自行百度
grant_type client_credentials //客户端方式 强制格式
grant_type password //用户密码方式 强制格式
三、创建Api,修改Startup.cs
1. 配置服务
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication("Bearer")
//.AddIdentityServerAuthentication(options =>
// {
// options.Authority = "http://localhost:5000";
// options.RequireHttpsMetadata = false;
// options.ApiName = "MyApi";
// })
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:5001";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
//API授权
services.AddAuthorization(options =>
{
//策略
options.AddPolicy("ApiScope", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("scope", "MyApi");
});
});
services.AddControllers();
}
2. 添加中间件
// Configure UseRouting与UseAuthorization中间件之间添加
app.UseAuthentication();
3. 给控制器活着Action 添加验证特性Authorize
/// <summary>
/// 需要授权的接口
/// </summary>
/// <returns></returns>
[Authorize]
[HttpGet]
public string get()
{
return "返回结果";
}
4. 给api添加获取Token接口
此处前端传参、写配置,活着硬编码都可
[HttpPost]
public async Task<string> access_tokenAsync(PasswordTokenRequest request)
{
// discover endpoints from metadata
var client = new HttpClient();
var disco =await client.GetDiscoveryDocumentAsync("http://localhost:5001");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
}
request.Address = disco.TokenEndpoint;
var tokenResponse = await client.RequestPasswordTokenAsync(request);
//new PasswordTokenRequest
//{
// Address = disco.TokenEndpoint,
// ClientId = "clientId",
// ClientSecret = "clientSecrets",
// UserName = "alice",
// Password = "password",
// Scope = "api1",
//});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
}
return tokenResponse.Json["access_token"].ToString();
}
5. 拿到Token后请求受保护的接口