IdentityServer4之ClientCredentials(客户端凭据许可)
IdentityServer4之ClientCredentials(客户端凭据许可)
1. 创建IdentityServer4服务
这里使用VS2019创建.net5.0框架下的IdentityServer4服务项目,命名为“IdentityServer4_ClientCredentials”,端口设置为5001。
通过Nuget安装IdentityServer4命令如下,记得程序包管理控制套,上面的项目选择刚刚创建的IdentityServer项目,代码如下:
Install-Package IdentityServer4
2. 配置身份服务器
Defining an API Scope
API 是系统中要保护的资源。资源定义可以通过多种方式加载,用于创建上述项目的模板显示了如何使用“代码即配置”方法。
创建Config.cs文件,代码如下所示:
public static class Config
{
public static IEnumerable IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
// v4新增
public static IEnumerable ApiScopes =>
new ApiScope[] {
new ApiScope("OrderApi","Order Api")
};
public static IEnumerable Clients =>
new Client[]
{ //客户端的唯一标识 此模式可用于前端
new Client
{
// 客户端的唯一标识
ClientId="client",
// 客户端认证密码
ClientSecrets = { new Secret("ordersecret".Sha256()) },
// 指定授权模式,这里指定为客户端凭据模式
AllowedGrantTypes = GrantTypes.ClientCredentials,
// 指定客户端获取的Token能访问到的作用域
AllowedScopes={ "OrderApi" }
}};
}
引用命名空间:
using IdentityServer4.Models;
3. 配置身份服务器
修改Startup.cs文件。
加载加载资源和客户端:代码如下:
public void ConfigureServices(IServiceCollection services)
{
// uncomment, if you want to add an MVC-based UI
//services.AddControllersWithViews();
var builder = services.AddIdentityServer(options =>
{
// see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
options.EmitStaticAudienceClaim = true;
})
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients);
// not recommended for production - you need to store your key material somewhere secure
builder.AddDeveloperSigningCredential();
}
身份验证服务添加到 DI(依赖注入)并将身份验证中间件添加到管道中
app.UseIdentityServer();
4. 创建WebAPI服务
这里创建一个订单服务,命名为OrderApi,端口为62274。
为控制器添加授权要求:
添加Microsoft.AspNetCore.Authentication.JwtBearer引用
注册认证相关组件和配置defaultScheme为Bearer,代码:
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
// 指定要接入的授权服务器地址
options.Authority = "http://localhost:5000";
// 在验证token时,不验证Audience
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
// 不适用Https
options.RequireHttpsMetadata = false;
});
Setup的Configure方法中添加认证和授权中间件,代码:
// 注册认证过滤器,在授权过滤器前面
app.UseAuthentication();
// 注册授权过滤器
app.UseAuthorization();
5. 创建客户端
创建WinFrom客户端,命名为WinFormsClient,在默认的Form1窗体中添加按钮和文本框用于调用接口和查看接口返回值,这里直接调用自带的温度接口。
代码如下:
private async void button1_Click(object sender, EventArgs e)
{
await Post();
}
private async Task Post()
{
// 1. 创建一个HttpClient用于请求
var client = new HttpClient();
// 2. 获取授权服务器的相关信息,IdentityModel已经将其封装好了
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
// 3. 检查是否请求错误
if (disco.IsError)
{
// 错误就打印错误信息,然后直接返回
textBox1.Text = disco.Error;
return;
}
// 4. 通过授权服务分配的标识,向授权服务器请求AccessToken
var tokenResp = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
// 指定获取token的地址,IdentityModel进行封装,直接使用即可
Address = disco.TokenEndpoint,
// 指定授权服务器分配的客户端标识
ClientId = "client",
// 指定授权服务器分的客户端密码
ClientSecret = "ordersecret"
});
// 5. 检查获取Token是否成功
if (tokenResp.IsError)
{
// 如果失败,打印错误消息并返回
textBox1.Text = tokenResp.Error;
return;
}
// 6. 创建一个请求API资源的HttpClient
var apiClient = new HttpClient();
// 7. 将获取到的Token以Bearer的方案设置在请求头中
apiClient.SetBearerToken(tokenResp.AccessToken);
// 8. 向资源服务器中请求受保护的API
var contentResp = await apiClient.GetAsync("http://localhost:62274/weatherforecast");
// 9. 打印对应的消息
if (contentResp.IsSuccessStatusCode)
{
var content = await contentResp.Content.ReadAsStringAsync();
textBox1.Text = content;
}
else
{
textBox1.Text = contentResp.StatusCode.ToString();
}
}
6.调用接口
设置多启动项目,运行。
点击调用接口按钮:
鸣谢:
https://github.com/IdentityServer
https://mp.weixin.qq.com/s/5B22Q9yBYqFFDBzOWxeP7w
源码
https://github.com/yandaniugithub/NETCore