(给DotNet加星标,提升.Net技能)

转自:朝闲cnblogs.com/Zing/p/13361386.html

前言

1、源码(.NET Core 2.2)

git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git

2、相关章节

2.1、《IdentityServer4 (1) 客户端授权模式(Client Credentials)》

2.2、《IdentityServer4 (2) 密码授权(Resource Owner Password)》

2.3、《IdentityServer4 (3) 授权码模式(Authorization Code)》

2.4、《IdentityServer4 (4) 静默刷新(Implicit)》

2.5、《IdentityServer4 (5) 混合模式(Hybrid)》

3、参考资料

IdentityServer4 中文文档 http://www.identityserver.com.cn/

IdentityServer4 英文文档 https://identityserver4.readthedocs.io/en/latest/

4、流程图

客户端授权模式是最基本的使用场景,我们需要做一个API(受保护的资源),一个客户端(访问的应用),一个IdentityServer(用来授权)

一、创建IdentityServer

1、用VS创建一个Web 项目

2、添加引用 IdentityServer4 包,下图是我已经安装好了的截图

3、添加一个配置文件(这里也可以使用json文件)

public class IdpConfig{/// /// 用户认证信息/// /// public static IEnumerableGetApiResources(){return new List        {new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Address(),new IdentityResources.Email(),new IdentityResources.Phone()        };    }/// /// API 资源/// /// public static IEnumerableGetApis(){return new List        {new ApiResource("api1", "My API")        };    }/// /// 客户端应用/// /// public static IEnumerableGetClients(){return new List        {new Client            {// 客户端ID 这个很重要                ClientId = "client",//AccessToken 过期时间,默认3600秒,注意这里直接设置5秒过期是不管用的,解决方案继续看下面 API资源添加JWT//AccessTokenLifetime=5,// 没有交互性用户,使用 clientid/secret 实现认证。                AllowedGrantTypes = GrantTypes.ClientCredentials,// 用于认证的密码                ClientSecrets =                {new Secret("secret".Sha256())                },// 客户端有权访问的范围(Scopes)                AllowedScopes = { "api1" }            }        };    }}

4、在StartUp.cs 里注册 IdentityServer4

ConfigureServices()

services.AddIdentityServer(options =>{    options.Events.RaiseErrorEvents = true;    options.Events.RaiseInformationEvents = true;    options.Events.RaiseFailureEvents = true;    options.Events.RaiseSuccessEvents = true;})  .AddDeveloperSigningCredential()//解决Keyset is missing 错误//.AddTestUsers(TestUsers.Users)//.AddInMemoryIdentityResources(IdpConfig.GetApiResources())  .AddInMemoryApiResources(IdpConfig.GetApis())  .AddInMemoryClients(IdpConfig.GetClients());

Configure()方法添加使用 IdentityServer4 中间件

app.UseIdentityServer();

5、配置完成

启动项目,访问 http://localhost:5002/.well-known/openid-configuration (我的端口号是5002) ,可以浏览 发现文档,参考下图,说明已经配置成功。

后面客户端会使用里面的数据进行请求toke

项目第一次启动根目录也会生成一个文件 tempkey.rsa

二、客户端

1、新建一个.Net Core Web 项目

这里可以使用其他建立客户端 。例如:控制台程序、wpf 等等。需要添加 NuGet 包 IdentityModel

2、新建一个 Controller 用来测试访问上面的IdentityServer

获取token,访问 http://localhost:5003/Idp/token ,提示访问成功

public class IdpController : Controller{private static readonly string _idpBaseUrl = "http://localhost:5002";public async TaskToken(){var client = new HttpClient();var disco = await client.GetDiscoveryDocumentAsync(_idpBaseUrl);if (disco.IsError)        {return Content("获取发现文档失败。error:" + disco.Error);        }var token = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()        {            Address = disco.TokenEndpoint,//ClientId、ClientSecret、Scope 这里要和 API 里定义的Client一模一样            ClientId = "client",            ClientSecret = "secret",            Scope = "api1"        });if (token.IsError)        {return Content("获取 AccessToken 失败。error:" + disco.Error);        }return Content("获取 AccessToken 成功。Token:" + token.AccessToken);    }}

三、添加API资源

1、新建一个API项目

我把API项目和IdentityServer 放到同一个解决方案,这个自己定,无所谓的

API资源指的是IdentityServer IdpConfig.GetApis() 里面添加的 api1(这个api1名称随便起,但是要注意一定要保持一致)

添加认证之后就可以测试用 AccessToken 请求资源了

2、添加JWT 认证

StartUp.ConfigureServices()

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>{// IdentityServer 地址    options.Authority = "http://localhost:5002";//不需要https    options.RequireHttpsMetadata = false;//这里要和 IdentityServer 定义的 api1 保持一致    options.Audience = "api1";//token 默认容忍5分钟过期时间偏移,这里设置为0,//这里就是为什么定义客户端设置了过期时间为5秒,过期后仍可以访问数据    options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;    options.Events = new JwtBearerEvents    {//AccessToken 验证失败        OnChallenge = op =>        {//跳过所有默认操作            op.HandleResponse();//下面是自定义返回消息//op.Response.Headers.Add("token", "401");            op.Response.ContentType = "application/json";            op.Response.StatusCode = StatusCodes.Status401Unauthorized;op.Response.WriteAsync(JsonConvert.SerializeObject(new            {                status = StatusCodes.Status401Unauthorized,                msg = "token无效"            }));return Task.CompletedTask;        }    };});

3、添加认证中间件

//这里注意 一定要在 UseMvc前面,顺序不可改变app.UseAuthentication();

4、Controller 添加特性认证 [Authorize]

[Route("api/[controller]")][Authorize]public class SuiBianController : Controller{    [HttpGet]public string Get(){var roles = User.Claims.Where(l => l.Type == ClaimTypes.Role);return "访问成功,当前用户角色 " + string.Join(',', roles.Select(l => l.Value));    }}

5、测试

访问 http://localhost:5001/api/suibian ,提示 token 无效,证明我们增加认证成功

四、客户端测试

1、修改 IdpController, 添加一个action 访问 API资源 /api/suibian

public class IdpController : Controller{//内存缓存 需要提前注册  services.AddMemoryCache();private IMemoryCache _memoryCache; private static readonly string _idpBaseUrl = "http://localhost:5002";private static readonly string _apiBaseUrl = "http://localhost:5001";public IdpController(IMemoryCache memoryCache){        _memoryCache = memoryCache;    }public async TaskToken(){var client = new HttpClient();var disco = await client.GetDiscoveryDocumentAsync(_idpBaseUrl);if (disco.IsError)        {return Content("获取发现文档失败。error:" + disco.Error);        }var token = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest()        {            Address = disco.TokenEndpoint,            ClientId = "client",            ClientSecret = "secret",            Scope = "api1"        });if (token.IsError)        {return Content("获取 AccessToken 失败。error:" + disco.Error);        }//将token 临时存储到 缓存中        _memoryCache.Set("AccessToken", token.AccessToken);return Content("获取 AccessToken 成功。Token:" + token.AccessToken);    }public async TaskSuiBian(){string token, apiurl = GetApiUrl("suibian");        _memoryCache.TryGetValue("AccessToken", out token);if (string.IsNullOrEmpty(token))        {return Content("token is null");        }var client = new HttpClient();        client.SetBearerToken(token);var response = await client.GetAsync(apiurl);var result = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode)        {            _memoryCache.Remove("AccessToken");return Content($"获取 {apiurl} 失败。StatusCode:{response.StatusCode} \r\n Token:{token} \r\n result:{result}");        }return Json(new        {            code = response.StatusCode,            data = result        });    }private string GetApiUrl(string address){return _apiBaseUrl + "/api/" + address;    }}

2、请求 AccessToken

http://localhost:5003/Idp/token ,请求成功后会将 token 存储到 cache 中

3、请求 API 资源

http://localhost:5003/Idp/suibian ,token是直接在缓存里面取出来的

五、项目目录

- EOF -

推荐阅读  点击标题可跳转

.NET hbase client--终于浮出水面的轮子

WinUI 3 试玩报告:10 篇热文汇总

ASP.NET Core监听SQL Server数据库的实时信息

看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能

好文章,我在看❤️

radmin提示授权码过期_IdentityServer4 客户端授权模式(Client Credentials)相关推荐

  1. oauth2.0授权码_OAUTH 2.0授权码授予

    oauth2.0授权码 OAuth 2.0提供了许多安全流程(或授权类型),以允许一个应用程序访问另一个应用程序中的用户数据. 在此博客中,我们将介绍OAuth 2.0授权:授权代码授权. 首先,有许 ...

  2. 基于oAuth2.0开发属于自己的SSO授权服务 - 授权码(Authourization Code)模式 (持续更新中。。。)

    此文章篇幅较长,平日上班较少时间写作,请见谅.持续更新中... oAuth2.0系列文章目录 #mermaid-svg-AZMPq56OmFj1I7k0 {font-family:"treb ...

  3. 【JVM】JVM客户端 server模式 client 模式

  4. blat+stunnel实践-命令行smtp发送邮件-通过QQ邮箱第三方客户端登录授权码

    2019独角兽企业重金招聘Python工程师标准>>> 背景: 工作中有一个业务需要每个月25号发送一个下月使用的文件给相关人员. 在此之前是用QQ邮箱的定时发送功能,先一次性地编缉 ...

  5. Oauth2系列2:授权码模式

    目录 传送门 再次重申oauth2的定义 定义 作用 标准授权码流程 4个参与角色 资源拥有者 客户端 授权服务 受保护资源 授权码流程 引导授权 获取code 用授权码code换取令牌token 返 ...

  6. 搭建认证服务器 - Spring Security Oauth2.0 集成 Jwt 之 【授权码认证流程】 总结

    在搭建介绍流程之前,确保您已经搭建了一个 Eureka 注册中心,因为没有注册中心的话会报错(也有可能我搭建的认证服务器是我项目的一个子模块的原因):Request execution error. ...

  7. 授权码模式-获取令牌

    (1)申请授权码 请求认证服务获取授权码: Get请求: http://localhost:9001/oauth/authorize? client_id=leon&response_type ...

  8. IdentityServer4之Authorization Code(授权码)相对更安全

    前言 接着授权模式聊,这次说说Authorization Code(授权码)模式,熟悉的微博接入.微信接入.QQ接入都是这种方式(这里说的是oauth2.0的授权码模式),从用户体验上来看,交互方式和 ...

  9. OAuth2.0授权码模式原理与实战

    OAuth2.0是目前比较流行的一种开源授权协议,可以用来授权第三方应用,允许在不将用户名和密码提供给第三方应用的情况下获取一定的用户资源,目前很多网站或APP基于微信或QQ的第三方登录方式都是基于O ...

最新文章

  1. 德国工业4.0眼里“工业互联网”与“智能制造”
  2. 使用JTextArea示例
  3. leetcode 106. 从中序与后序遍历序列构造二叉树 c语言递归解法
  4. 干货:TensorFlow1.2~2.1各个GPU版本CUDA和cuDNN对应版本整理
  5. VTK:图表之GraphToPolyData
  6. 深度学习之对象检测_深度学习时代您应该阅读的12篇文章,以了解对象检测
  7. WebForm 使用点滴。。。。
  8. C++Objective-c
  9. python高维数据_t-SNE高维数据可视化(python)
  10. 【TensorFlow】TensorFlow函数精讲之tf.clip_by_value()
  11. windows 搭建kms服务器激活_windows下搭建MQTT服务器
  12. Zerodium 称 iOS exploit 过剩,将暂停收购且买价或下跌
  13. 在 Ubuntu 和 Linux Mint 上释放空间的9种简单方法
  14. wps中下划线怎么也去不掉_黑头究竟怎么形成的?为什么总是去不掉?那是因为你用错方法...
  15. python—装饰器@lru_cache在递归中的使用
  16. 最全计算机基础知识竞赛试题,计算机基础知识竞赛试题.doc
  17. pyqt创建透明窗体
  18. 学习cairo的心得及资料
  19. 英语语法 定冠词与专有名词
  20. 校园闲置物品(跳蚤市场)交易平台的设计与实现

热门文章

  1. go环境搭建_学习的golang第一步,搭建我们运行的环境,go! go! go
  2. java 循环map 优雅写法_Java for循环Map集合优化实现解析
  3. seata xid是什么_阿里开源的分布式事务框架 Seata
  4. 安卓php推送消息机制,深入剖析Android消息机制原理
  5. 工业交换机常用术语及常见知识点汇总
  6. 【渝粤题库】陕西师范大学201451 中国法制史作业
  7. 2021年春季学期期末统一考试 国际公法 试题
  8. geteditor p 取消自动_2020百度网盘超级会员怎么取消自动续费?
  9. mysql数据库全备_MySQL innobackupex全备是指什么
  10. python蟒蛇代码_011 实例2-Python蟒蛇绘制