IdentityServer4专题之五:OpenID Connect及其Client Credentials流程模式
1.基于概念
OAuth2.0与身份认证协议的角色映射
OpenID Connect 这个协议是2014颁发的,基于OAuth2.0,在这个协议中,ID Token会和Access Token一起发回客户端应用,它还提供了一个UserInfo这个端点,通过此端点可以获取用户信息,还提供了一级标识身份的scopes和claims(profile、email、address、phone)
这个协议定义了三个流程:
Identity Server4.0的结构图
2.三种流程模式
IdentityServer上:
在startup.cs页面中ConfiureServices页面中,应将json config 方式改为code config方式。即按如下方式切换注释代码
// in-memory, code config
builder.AddInMemoryIdentityResources(Config.GetIdentityResources());
builder.AddInMemoryApiResources(Config.GetApis());
builder.AddInMemoryClients(Config.GetClients());
// in-memory, json config
//builder.AddInMemoryIdentityResources(Configuration.GetSection("IdentityResources"));
//builder.AddInMemoryApiResources(Configuration.GetSection("ApiResources"));
//builder.AddInMemoryClients(Configuration.GetSection("clients"));
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new ApiResource[]
{
new ApiResource("api1", "My API #1")
};
}
public static IEnumerable<Client> GetClients()
{
return new[]
{
// client credentials flow client
new Client
{
ClientId = "console client",
ClientName = "Client Credentials Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
AllowedScopes = {"api1" }
}
};
}
}
客户端控制台程序代码:
static async Task Main(string[] args)
{
//Discovery endpoint
Console.WriteLine("Hello World!");
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if(disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
//Request access token,客户端必须带有:ClientCredentials
var tokenResponse =await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest {
Address = disco.TokenEndpoint,
ClientId = "console client",
ClientSecret = "511536EF-F270-4058-80CA-1C89C192F69A",
Scope= "api1"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
var apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);
var response = await apiClient.GetAsync("http://localhost:5002/api/values");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}
asp.net core api资源应用:
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.AddMvcCore().AddAuthorization().AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.Audience = "api1";
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ //使用identityserver
app.UseAuthentication();
app.UseMvc();
}
}
[Route("api/[controller]")]
[Authorize]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2","value3"};
}
}
总结:Client Credentials这种方式,客户端应用不代表用户,客户端应用本身就相当于是资源所有者;通常用于机器对机器的通信;客户端也需要身份认证。
可采用工具软件监控客户端与服务端的通信:
将获取的access token放到网站https://jwt.io/,进行解码,即可以看到token中包含的许多用用信息。
最新文章
- IOS 2D游戏开发框架 SpriteKit-->;续(完善角色功能)
- Android 网络HTML查看器
- Python Queue队列
- Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0的区别
- iOS App上架流程(2016详细版
- UVA 253 Cube painting(暴力打表)
- maven+springMVC+mybatis+junit详细搭建过程 ***
- c语言下的通用数据库接口(之sqlite消化,模拟c#,java的反射)
- 蓝牙(3)如何通过蓝牙传输数据及UUID详介
- call()和apply()的区别
- INTELLIJ IDEA集成CHECKSTYLE(转)
- sqlserver 数据库里面金额类型为什么不建议用float,实例告诉你为什么不能。
- HDU2111 Saving HDU 【贪心】
- HDU2519:新生晚会
- selenium之元素定位-css
- 【CF480D】Parcels DP
- EasyUI 树形菜单加载父/子节点
- java各版本简单对比
- 数据集永久字段的Visble 属性为何不起作用
- JFinal架构简介
热门文章
- 通过aptitude降级包解决依赖问题(E:无法修正错误,因为您要求某些软件包保持现状)
- 【摘录自MDN】客户端和服务器
- JavaScript - call() , apply() and bind()
- 乒乓球(0)<;P2003_1>;
- Ubuntu开启端口(持久化)
- springboot搭建的web数据提交乱码
- 五 Action访问方法,method配置,通配符(常用),动态
- 吴裕雄--天生自然ORACLE数据库学习笔记:数据表对象
- in comment after two dashes (--) next character must be >; not - (position: START_TAG seen ...
- kafka控制测试发送接收消息