再谈使用IdentityServer实现ASP.NET Core Web API的认证与授权 - dax.net - 博客园

霄
2022-09-05 / 0 评论 / 24 阅读 / 正在检测是否收录...
  • 会员

  • 周边

  • 众包

  • 赞助商

                            所有博客

                                    当前博客

                                                [我的博客](https://passport.cnblogs.com/GetBlogApplyStatus.aspx)                            [我的园子](https://home.cnblogs.com/)                            [账号设置](https://account.cnblogs.com/settings/account)                            [
简洁模式 ...

](javascript:void(0))

                        [退出登录](javascript:void(0))                                            [注册](https://account.cnblogs.com/signup)[登录](javascript:void(0);)                     [](https://www.cnblogs.com/daxnet/)

Software on .NET/C#, Cloud, Microservices and DDD,专业、求是、解惑......

  • 博客园

  • 首页

  • 订阅

  • 管理

          随笔 - 309  文章 - 0  评论 - 2754  阅读 - 

    183万

注意:从2022年12月3日开始,社区版的IdentityServer4将不再被支持,所有的后续开发工作都将在

在讨论IdentityServer中的相关概念时,可以思考一下,一个基于角色的权限管理系统(RBAC)是如何实现的。总的来说,RBAC关心的是:用户或者用户组,对于什么样的资源,具有什么样的访问权限。比如:用户组A对于天气服务具有读取的权限,而对于国家信息查询服务则没有访问权限,而用户组B则恰好相反。在IdentityServer中,可以类比地将用户组看成Client;将天气服务、国家信息查询服务看成ApiResource,于是,访问权限的标记,则被看成是ApiScope。为什么说是“访问权限的标记”而不是“访问权限”呢?因为在IdentityServer中,访问权限的定义,是通过Client的AllowedScope以及API的Audience来设定的。ApiScope定义了一组标记,ApiResource可以使用这些标记来决定它能够支持哪些类型的权限设定,而Client又可以指定它能够使用哪些ApiScope来访问API。下面的代码中定义了3个ApiResource,通常情况下,一个ApiResource可以对应一个需要被IdentityServer鉴权的ASP.NET Core Web API应用程序:

?

| 1 | public |

在每个ApiResource定义中,它包含了三个信息:ApiResource的名称、描述,以及它所包含的ApiScope。例如:对于audit ApiResource,它的名称是audit,描述是Audit API,然后它所支持的ApiScope包括audit.query和audit.insert。ApiScope的定义如下:

?

| 1 | public |

可以看到,ApiScope其实就是定义了一个字符串标记,这个标记建立了Client与ApiResource之间的关系,不仅如此,ApiScope还会以Claim的形式传递给受保护的Web API,以便完成API访问授权。那么对于一个IdentityServer Client,它就可以指定所允许使用的ApiScope有哪些:

?

| 1 | public |

在上面的代码中,m2m.client这个Client它指定了AllowedScope只能是management.read和management.create,因此,对于这个Client而言,它只能用来访问management这个ApiResource(其实也就是Audience为management的ASP.NET Core Web API应用程序),并且仅能访问这个ApiResource中被标记为management.read和management.create的API端点。这一部分后续会介绍。不要忘记在ASP.NET Core中使用IdentityServer:

?

| 1 | builder.Services |

配置好IdentityServer应用程序后,启动应用程序,然后使用Postman来调用/connect/token这个API端点,以获得Jwt Access Token:对应的cURL命令如下:

?

| 1 | curl -L -X POST |

此时,会请求/connect/token端点,通过传入client_id、client_secret、grant_type、response_type以及scope这些参数,来获得Jwt Access Token。这里的scope必须是之前Client中定义的AllowedScopes的子集,或者与之相同,否则会出现invalid_scope的错误。其它的参数也都是与Client的设置相匹配,因此,通过调用这个API获得的Jwt Access Token就只能访问management API,并且只能访问被标记为“读取”(read)和“创建”(create)的API端点。不过,这还需要配合受保护的Web API应用程序中对于授权(Authorization)的实现。接下来,配置我们的Web API应用程序,使其受保护于IdentityServer。在Program.cs中,加入下面的代码:

?

| 1 | builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) |

注意这里的Authority为IdentityServer的地址,Audience则为IdentityServer中所设置的对应的ApiResource的名字。上面所获得的Access Token所包含的scope信息为management.read和management.create,两者都是management这个ApiResource所定义的ApiScope,因此,这个Access Token是可以访问我们的Web API的,因为它的Audience正是management。接下来,在Controller上加上Authorize特性即可:

?

| 1 | [ApiController] |

此时,如果使用Postman来访问MeetingRoomsController中的Get方法,则会返回401 Unauthorized的错误:现在,在Postman中,将Auth的Type切换为Bearer Token,然后将Token的值设置为上面所获得的Access Token,再次调用上面的API,此时返回200 OK,调用成功:ASP.NET Core Web API应用程序还可以基于IdentityServer中所设定的ApiScope来进行基于Claim的访问授权。比如:这里的Access Token仅具有management.read和management.create这两个scope,因此,它理应只能访问Web API应用程序中具有读取和创建功能的API,这可以通过配置Web API应用程序来实现。在Web API应用程序的Program.cs中,加入下面的代码:

?

| 1 | builder.Services.AddAuthorization(options => |

这段代码在Web API授权体系中加入了4个策略(Policy),这些Policy会要求Claims中有一个名为scope的Claim,并且具有所对应的值。于是,被标记为management.read这一授权策略的API,在被访问前,ASP.NET Core Web API就会检查Claims中是否有一个的scope为management.read,如果没有,则返回403 Forbidden。要使用Authorization Policy对API进行标记,需要在Controller中的不同的Action上使用Authorize特性来标记,它告诉Web API框架,当前这个API需要采用什么样的授权策略。下面的代码展示了如何使用Authorize特性来针对不同的API采用不同的授权策略:

?

| 1 | [ApiController] |

现在,如果使用同样的Access Token来访问GetMeetingRoom和GetMeetingRooms这两个API,则都能成功。然而,如果访问DeleteMeetingRoom这个API,则返回403 Forbidden。因为这个Access Token没有包含management.delete这个scope:到此为止,我们已经在ASP.NET Core Web API下实现了基于IdentityServer的ApiResource和ApiScope的认证与授权。

    [好文要顶](javascript:void(0);)        [关注我](javascript:void(0);)    [收藏该文](javascript:void(0);)    [微信分享](javascript:void(0);)                [](https://home.cnblogs.com/u/daxnet/)

                [dax.net](https://home.cnblogs.com/u/daxnet/)                

        [粉丝 - 3067](https://home.cnblogs.com/u/daxnet/followers/)            [关注 - 21](https://home.cnblogs.com/u/daxnet/followees/)

            [会员号:3853](https://cnblogs.vip/)                    

推荐博客

            [+加关注](javascript:void(0);)        

    0        

    0            

升级成为会员 « 上一篇: 使用C#和MonoGame开发俄罗斯方块游戏

[» ](https://www.cnblogs.com/daxnet/p/18114010) 下一篇:    [再谈基于Ocelot API网关和IdentityServer的API认证与授权](https://www.cnblogs.com/daxnet/p/18114010)                        

posted @ 2022-07-12 21:41 dax.net 阅读(24) 评论(0) 编辑 收藏 举报 会员力量,点亮园子希望

刷新页面返回顶部

登录后才能查看或发表评论,立即 [登录](javascript:void(0);) 或者    [逛逛](https://www.cnblogs.com/) 博客园首页            [【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步](http://ishell.cc/)

【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!

【推荐】会员力量,点亮园子希望,期待您升级成为博客园VIP会员

                    [


        ](https://cnblogs.vip/)

        **编辑推荐:**

· 架构师备考的一些思考

· 利用分布式锁在 ASP.NET Core 中实现防抖

· 写在临近40岁的年龄

· 一场 Kafka CRC 异常引发的血案

· 记录荒废了三年的四年.net开发的第三次面试

    **阅读排行:**    

· 40岁大龄失业程序猿,未来该何去何从

· .NET 8.0 文档管理系统网盘功能的实现

· 神奇的C语言输出12天圣诞节歌词代码

· 牛逼!Vue3.5的useTemplateRef让ref操作DOM更加丝滑

· 一个开源、跨平台的.NET UI框架 - Avalonia UI

**历史上的今天:**

2017-07-12 在Apworks数据服务中使用基于Entity Framework Core的仓储(Repository)实现

公告 陈晴阳(Sunny Chen),2003年毕业于中南大学铁道校区(原长沙铁道学院),高级程序员(2004年),系统分析员(2006年),微软认证专家(MCP 2004),前微软最有价值专家(MVP,2012-2019)。cnblogs网名daxnet,并打算以该名闯荡IT江湖。曾经使用Microsoft Dynamics AX近六年,现专注于Microsoft .NET、.NET Core和Visual C#,是领域驱动设计与微服务、云架构设计的忠实爱好者和实践者。 昵称:

园龄:    [
    14年5个月
](https://home.cnblogs.com/u/daxnet/)    

荣誉: 推荐博客

粉丝:    [
    3067
](https://home.cnblogs.com/u/daxnet/followers/)    

关注:    [
    21
](https://home.cnblogs.com/u/daxnet/followees/)    

+加关注

| |
| -- | -- | -- | -- | -- | -- | -- |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |

积分与排名

  •   积分 -    

    505693

  •   排名 -    

    1320

随笔档案
(309)

    1. Re:基于MonoGame重制《俄罗斯方块》游戏
  • @描我白 厉害了,博主。 谢谢支持,互相学习...

  • --dax.net

    1. Re:基于MonoGame重制《俄罗斯方块》游戏
  • 厉害了,博主。

  • --描我白

    1. Re:.NET科普:.NET简史、.NET Standard以及C#和.NET Framework之间的关系
  • @dax.net 现在用.net开发人员我认为是无须了解.net standard这个玩意的。...

  • --首席装逼官

    1. Re:.NET科普:.NET简史、.NET Standard以及C#和.NET Framework之间的关系
  • @首席装逼官 net standard是一个netcore取代netframework的一个中间概念,主要是为了不同版本的做兼容性,现在可以不用考虑和关注这个概念了。 没错,只是现在还是有很多用.NE...

  • --dax.net

    1. Re:.NET科普:.NET简史、.NET Standard以及C#和.NET Framework之间的关系
  • 还是那句:

|微软误我啊.

  • --迅捷网络[来送福利] Copyright © 2024 dax.net

Powered by .NET 8.0 on Kubernetes

点击右上角即可分享

[

  ](https://www.cnblogs.com/cmt/p/18302049)
扫描二维码,在手机上阅读!
82

评论

博主关闭了当前页面的评论