IdentityServer4实现OAuth2.0四种模式之客户端模式
一,准备内容
IdentityServer4 是Asp.net core的一个中间件,用于添加符合OpenId Connect和OAuth2.0规范的终端到Asp.net Core应用。在这里简单介绍一下Openid和OAuth2.0。
OpenId:用户身份认证(Authentication )。当用户(End User)在微信、Google等OpenId提供者(OpenID Provider)平台注册账户时会产生一个身份标识,这个身份标识就是OpenId,当用户登录第三方应用(Relying Part)时如果Relying Part支持OpenId登录,会生成一个带有重定向地址的Url跳至OpenId Provider平台登录界面,用户登录成功后,根据重定向地址带着OpenId跳回Relying Part,标识着用户身份认证成功,该用户在OpenId Provider平台有注册。Relying Part根据OpenId自动注册账户,至此身份认证结束。有时Relying Part需要从Openid Provider那获取该用户的更多信息或资源,OpenId Provider需要对Relying Part的请求进行授权管理,这时就用要到OAuth2.0。
OAuth2.0:用户访问授权(Authorization)。OAuth2.0是一个JWT(Json Web Token ,Json格式Web令牌)解决方案。其最终目的是给用户一个包含加密令牌的JSON字符串,这个令牌内包含授权信息,决定了该用户可以访问那些资源。OAuth2.0协议规定了4种取得令牌的方式,可以参考这篇文章OAuth2.0的四种方式。
Openid Connect:实际上就是将Openid与OAuth2.0结合起来,解决身份认证和身份授权的问题。
客户端模式只对客户端进行授权,不涉及到用户信息。如果你的api需要提供到第三方应用,第三方应用自己做用户授权,不需要用到你的用户资源,就可以用客户端模式,只对客户端进行授权访问api资源。
二,创建Asp.net Core 项目
微软提供了一些针对IdentityServer4的项目模板,在命令行中输入” dotnet new -i IdentityServer4.Templates“即可安装,安装好后可以看到当前已安装的项目模板,其中有一个"is4empty",其实就是一个asp.net core 应用装了IdentityServer4包。在命令行中输入:dotnet new is4empty -n Projectname 就会根据这个模板生成一个新项目。下图是我的项目,一个api客户端、一个mvc客户端,一个identityserver4服务端,其中Api客户端是受保护的Api资源,Mvc客户端是第三方客户端,用于访问被保护的Api客户端,可以看成是任意后端程序。

- 配置IdentityServer服务器,如果是用的is4empty模板创建的项目,已经有一些简单配置,后面我们慢慢深化
public void ConfigureServices(IServiceCollection services)
{
//添加IdentityServer
var builder = services.AddIdentityServer()
//身份信息授权资源
.AddInMemoryIdentityResources(Config.GetIdentityResources())
//API访问授权资源
.AddInMemoryApiResources(Config.GetApis())
//添加客户端
.AddInMemoryClients(Config.GetClients()); if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
else
{
throw new Exception("need to configure key material");
}
} public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//使用IdentityServer中间件
app.UseIdentityServer();
}
为了能更好的查看调试日志,使用窗口调试,可以在Properties/launchSettings.json中可以更改监听地址,默认为5000

启动项目后使用浏览器打开:http://localhost:5000/.well-known/openid-configuration。可以看到identityserver4的discover说明。
三,配置IdentityServer4
1,添加ApiResource:修改IdentityServer项目的Config类的GetClients方法,添加一个api资源(ApiResource)。每个被保护的API项目必需有对应一个ApiResource,一个ApiResource可以有被多个API标识,客户端请求令牌时根据ApiResource名称决定是否有权限访问这个API。
public static IEnumerable<ApiResource> GetApis()
{
return new ApiResource[] {
//secretapi:标识名称,Secret Api:显示名称,可以自定义
new ApiResource("secretapi","Secret Api")
};
}
2,添加客户端模式用户:定义好ApiResouce后,再来添加一个客户端,使得这个客户端可以访问secretapi这个资源。修改Config类中的GetClients方法,添加一个用户用于支持客户端模式的请求。
public static IEnumerable<Client> GetClients()
{
return new Client[] { new Client()
{
//客户端Id
ClientId="apiClientCd",
//客户端密码
ClientSecrets={new Secret("apiSecret".Sha256()) },
//客户端授权类型,ClientCredentials:客户端凭证方式
AllowedGrantTypes=GrantTypes.ClientCredentials,
//允许访问的资源
AllowedScopes={
"secretapi"
}
}
};
}
四,配置API客户端
1,配置API项目监听端口和调试方式

2,配置Api项目认证
IdentityApi.Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication("Bearer").AddJwtBearer(r => {
//认证地址
r.Authority = "http://localhost:5000";
//权限标识
r.Audience = "secretapi";
//是否必需HTTPS
r.RequireHttpsMetadata = false;
});
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
//使用认证中间件
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
3,添加接口:新建一个空的Api控制器(IdentityController),在这个控制器中添加一个Api:GetUserClaims
[ApiController]
public class IdentityController : ControllerBase
{
[HttpGet]
[Route("api/identity")]
[Microsoft.AspNetCore.Authorization.Authorize]
public object GetUserClaims()
{
return User.Claims.Select(r => new { r.Type, r.Value });
}
}
这时GetUserClaims这个Api是访问不了的,用PostMan访问时返回401未认证状态

五,访问受保护的Api
要访问上面那个受保护的Api,分为2步,第一步从IdentityServer获取token,第二步把这个token使用Bearer authorization 方式添加到Http请求头。
1,在IdentityMvc项目访问受保护的Api
IdentityMvc项目安装一个Nuget包:IdentityModel,这个包对HttpClient对象有扩写,封装了一些IdentityServer的常用请求。修改IdentityServer的监听端口为5002,使用窗口调试。
在IdentityMvc的HomeController.cs新增一个控制器GetData
public async Task<IActionResult> GetData()
{
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
return new JsonResult(new { err=disco.Error});
var token= await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest() {
//获取Token的地址
Address = disco.TokenEndpoint,
//客户端Id
ClientId = "apiClientCd",
//客户端密码
ClientSecret = "apiSecret",
//要访问的api资源
Scope = "secretapi"
});
if (token.IsError)
return new JsonResult(new { err = token.Error });
client.SetBearerToken(token.AccessToken);
string data = await client.GetStringAsync("https://localhost:5001/api/identity");
JArray json = JArray.Parse(data);
return new JsonResult(json);
}
访问https://localhost:5002/home/getdata可以看到已经成功返回数据

2,使用原生HTTP请求访问受保护的Api
获取access_token:直接打开http://localhost:5000/.well-known/openid-configuration,找到token_endpoint节点

使用PostMan对该节点发送如下Post请求获取access_token

访问被保护的Api
由于使用的是Bearer认证机制,所以添加一个名为Authorization的Http请求头,请求头的内容是字符串“Bearer”+空格+获取到的Token:Bearer Token
下一篇:dentityServer4实现OAuth2.0之密码模式.
IdentityServer4实现OAuth2.0四种模式之客户端模式的更多相关文章
- IdentityServer4 实现OAuth2.0四种模式之密码模式
接上一篇:IdentityServer4 实现OAuth2.0四种模式之客户端模式,这一篇讲IdentityServer4 使用密码模式保护API访问. 一,IdentityServer配置 1,添加 ...
- IdentityServer4实现Oauth2.0四种模式之隐藏模式
接上一篇:IdentityServer4实现OAuth2.0四种模式之密码模式,密码模式将用户的密码暴露给了客户端,这无疑是不安全的,隐藏模式可以解决这个问题,由用户自己在IdentityServ ...
- IdentityServer4实现OAuth2.0四种模式之授权码模式
接上一篇:IdentityServer4实现OAuth2.0四种模式之隐藏模式 授权码模式隐藏码模式最大不同是授权码模式不直接返回token,而是先返回一个授权码,然后再根据这个授权码去请求token ...
- OAuth2.0 四种授权模式
OAuth2.0简单笔记(四种授权模式) 金天:坚持写东西,不是一件容易的事,换句话说其实坚持本身都不是一件容易的事.如果学习有捷径,那就是不断实践,不断积累.写笔记,其实是给自己看的,是体现积累的一 ...
- 快速了解yuv4:4:4 yuv4:2:2 yuv 4:1:1 yuv 4:2:0四种YUV格式区别
四种YUV格式区别如下: 1.YUV 4:4:4抽样方式: Y: Y0 Y1 Y2 Y3 U: U0 U1 U2 U3 V: V0 V1 V2 V3 2.YUV 4:2:2抽样方式: Y : ...
- JS创建对象的四种简单方式 (工厂模式和自定义构造函数创建对象的区别)
// 对象:特指的某个事物,具有属性和方法(一组无序的属性的集合) // 特征------>属性 // 行为------>方法 // 创建对象的四种方式 1 // 1.字面量的方式,就是实 ...
- 四种webAPP横向滑动模式图解—H5页面开发
一.容器整体滑动(DEMO只演示A-B-C-B,下同) 模拟动画效果见下图(上),滑动分解见下图(下): DEMO地址:http://nirvana.sinaapp.com/demo_slider/s ...
- Apache Oltu 实现 OAuth2.0 服务端【授权码模式(Authorization Code)】
要实现OAuth服务端,就得先理解客户端的调用流程,服务提供商实现可能也有些区别,实现OAuth服务端的方式很多,具体可能看 http://oauth.net/code/ 各语言的实现有(我使用了Ap ...
- 二十四种设计模式:命令模式(Command Pattern)
命令模式(Command Pattern) 介绍将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可取消的操作. 示例有一个Message实体类,某个 ...
随机推荐
- Comparison of SIFT Encoded and Deep Learning Features for the Classification and Detection of Esca Disease in Bordeaux Vineyards(分类MobileNet,目标检测 RetinaNet)
识别葡萄的一种虫害,比较了传统SIFT和深度学习分类,最后还做了目标检测 分类用的 MobileNet,目标检测 RetinaNet MobileNet 是将传统深度可分离卷积分成了两步,深度卷积和逐 ...
- 微信小程序之如何定义页面标题
效果图: 这个标题是在哪里定义的呢?type.js核心代码如下(通常这段代码放在onLoad函数体内): wx.setNavigationBarTitle({ title: "支出类型列表& ...
- 【大数据作业九】安装关系型数据库MySQL 安装大数据处理框架Hadoop
作业要求:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 4.简述Hadoop平台的起源.发展历史与应用现状. 列举发展过程中 ...
- IOC注解详解
@Component 修改一个类,将这个类交给Spring管理 相当于在配置文件当中配置<bean id="" class=""> @Compone ...
- Cesium的Property机制总结[转]
https://www.jianshu.com/p/f0b47997224c 前言 Cesium官方教程中有一篇叫<空间数据可视化>(Visualizing Spatial Data).该 ...
- 开启Nginx监控 with-http_stub_status_module
1.开启监控with-http_stub_status_module ./configure --with-openssl=/usr/local/ssl --with-http_stub_stat ...
- MacOS Laravel 安装教程
一.到官网选择 Laravel 版本 根据个人的喜好选择安装的版本,我选择的是 5.8 https://laravel.com/docs/5.8/installation 以下是 Laravel 5. ...
- 使用create-react-app遇到问题解决方案汇总
使用create-react-app时遇到Module not found问题 转 https://blog.csdn.net/wkq_1212/article/details/90291558 本来 ...
- Android 动态更换桌面图标
每当双 11.12 来临之际,Android 手机 Launcher 中的淘宝.天猫图标就会变成双 11.12 主题的图标.实现了动态切换图标.名称 MainActivity package com. ...
- 同时购入两台同款thinkpad笔记本电脑,分别使用同一账户激活office失败--------------解决方法(账户下有多个Office激活信息,重装后提示“许可证不正确或者最大激活次数”)
如题所述,该问题曾多次与京东商城售后,京东thinkpad品牌售后,thinkpad售后等进行沟通,最后通过微软的电话激活才成功,不过在之后发现了这么一个帖子,应该是官方给出的,应该合理,没有实际验证 ...