IdentityServer4 4.x版本 配置Scope的正确姿势

点击上方蓝字"小黑在哪里"关注我吧

前言

IdentityServer4 是为ASP.NET Core系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证的框架

IdentityServer4官方文档:https://identityserver4.readthedocs.io/

看这篇文章前默认你对IdentityServer4 已经有一些了解。

本篇使用IdentityServer4的4.x版本,跟老版本的稍微有些差别。下面直接进入正题。

鉴权中心

创建IdentityServer4项目

使用IdentityServer4 来搭建一个鉴权中心,首先建议安装一下IdentityServer4的官方项目模板。也可以不安装,自己创建项目,然后NuGet安装需要的包也行。(不过还是推荐用官方的模板,很方便)。

命令行执行:dotnet new -i IdentityServer4.Templates

image-20200629205619088

安装完成后会多出以下项目模板:

image-20200629205731577

我这里选用is4inmem这个模板来创建项目,这个模板的数据都是写死在内存中的,并且包含了Quickstart页面,比较简单方便。

来到我的项目目录下执行:dotnet new is4inmem --name Idp

image-20200701190325246

执行完成会生成以下文件:

image-20200701195853822

VS2019打开项目:

image-20200701195955107

运行项目:

image-20200701200225015

配置ApiResource、ApiScope、Clients

修改Startup:

// in-memory, code config
builder.AddInMemoryIdentityResources(Config.IdentityResources);
builder.AddInMemoryApiScopes(Config.ApiScopes);
//添加API资源
builder.AddInMemoryApiResources(Config.ApiResources);
builder.AddInMemoryClients(Config.Clients);

这里比之前版本多了一个添加ApiScopes的方法:

builder.AddInMemoryApiScopes(Config.ApiScopes);

因为我接下来有要保护的API资源,所以需要添加一行:

builder.AddInMemoryApiResources(Config.ApiResources);

Config中的代码:

public static class Config
{public static IEnumerable<IdentityResource> IdentityResources =>new IdentityResource[]{new IdentityResources.OpenId(),new IdentityResources.Profile(),};public static IEnumerable<ApiScope> ApiScopes =>new ApiScope[]{new ApiScope("scope1"),//new ApiScope("scope2"),};public static IEnumerable<ApiResource> ApiResources =>new ApiResource[]{new ApiResource("api1","#api1"){//!!!重要Scopes = { "scope1"}},//new ApiResource("api2","#api2")//{//    //!!!重要//    Scopes = { "scope2"}//},};public static IEnumerable<Client> Clients =>new Client[]{new Client{ClientId = "postman client",ClientName = "Client Credentials Client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets = { new Secret("postman secret".Sha256()) },AllowedScopes = { "scope1" }},};
}

我添加了一个ID为postman client的客户端,授权模式就用最简单的ClientCredentials客户端模式。需要注意的是4.x版本的ApiScope和ApiResource是分开配置的,然后在ApiResource中一定要添加Scopes。如果你在网上搜的IdentityServer4教程比较老的,都是没有这个ApiScope的,默认ApiResource的Name作为Scope。类似这样:

public static IEnumerable<ApiResource> ApiResources =>new ApiResource[]{new ApiResource("api1","#api1"),//错误new ApiResource("api2","#api2"),//错误};public static IEnumerable<Client> Clients =>new Client[]{new Client{......AllowedScopes = { "api1", "api2" }},};

如果你这么写的话,虽然不影响你获取token,但是你访问api资源的话,永远会得到一个401错误!!!

ApiResource

下面添加一个api1资源,新建asp.netcore web应用并使用webapi模板:

image-20200701211036365

NuGet安装:Microsoft.AspNetCore.Authentication.JwtBearer

Startup部分代码:

public void ConfigureServices(IServiceCollection services)
{services.AddControllers();services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{//IdentityServer地址options.Authority = "http://localhost:5001";//对应Idp中ApiResource的Nameoptions.Audience = "api1";//不使用httpsoptions.RequireHttpsMetadata = false;});
}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseHttpsRedirection();app.UseRouting();//身份验证app.UseAuthentication();//授权app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});
}

给WeatherForecastController添加[Authorize]标记:

image-20200701214601854

运行Api1Resource,用postman测试访问weatherforecast接口:

image-20200701214742071

此时得到401错误。下面先去Idp获取一个token:

image-20200701215031535

拿到token后再去访问weatherforecast就没问题了:

image-20200701215748634

进行到这里,好像跟scope都没什么关系,那么scope到底有什么用处呢?

ApiScope策略授权

继续修改代码。

Api1Resource项目NuGet安装:IdentityServer4.AccessTokenValidation

image-20200701221017612

再新建一个TestController用于区分:

image-20200701223359517

下面我需要做的是使用scope结合策略授权来分别限制TestController和WeatherForecastController的访问权限。

修改Startup:

public void ConfigureServices(IServiceCollection services)
{......services.AddAuthorization(options =>{//基于策略授权options.AddPolicy("WeatherPolicy", builder =>{//客户端Scope中包含api1.weather.scope才能访问builder.RequireScope("api1.weather.scope");});//基于策略授权options.AddPolicy("TestPolicy", builder =>{//客户端Scope中包含api1.test.scope才能访问builder.RequireScope("api1.test.scope");});});
}

为了好理解,我把scope名称分别改成了:api1.weather.scope和api1.test.scope。

WeatherForecastController的Authorize标记修改一下:[Authorize(Policy = "WeatherPolicy")]

TestController的代码很简单:

image-20200701224046637

因为修改了scope名称,需要把Idp中的scope名称也改一下:

public static IEnumerable<ApiScope> ApiScopes =>new ApiScope[]{new ApiScope("api1.weather.scope"),new ApiScope("api1.test.scope"),//new ApiScope("scope2"),};public static IEnumerable<ApiResource> ApiResources =>new ApiResource[]{new ApiResource("api1","#api1"){//!!!重要Scopes = { "api1.weather.scope", "api1.test.scope" }},//new ApiResource("api2","#api2")//{//    //!!!重要//    Scopes = { "scope2"}//},};

客户端定义,AllowedScopes暂时只给一个api1.weather.scope测试一下

public static IEnumerable<Client> Clients =>new Client[]{new Client{ClientId = "postman client",ClientName = "Client Credentials Client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets = { new Secret("postman secret".Sha256()) },AllowedScopes = { "api1.weather.scope" }},};

postman获取token:

image-20200701225242813

访问weatherforecast接口,正常响应200。

image-20200701225430395

再访问test,得到403错误:

image-20200701225508071

接下来修改一下Idp的客户端定义,添加api1.test.scope:

AllowedScopes = { "api1.weather.scope", "api1.test.scope" }

修改Idp后一定要重新获取token,jwt就是这样,一旦生成就无法改变。

image-20200701230022811

拿到新的token后访问test和weatherforecast,这时候就都可以正常响应了。

image-20200701230107290
image-20200701230209695

总结

以上使用IdentityServer4搭建了一个鉴权中心,保护API资源,并使用ApiScope配合策略授权完成了一个简单的权限控制。IdentityServer4的玩法非常多,知识点也很多。强烈推荐B站的@solenovex 杨老师的视频,地址:https://www.bilibili.com/video/BV16b411k7yM 多看几遍,会有收获。。。

需要代码的点这里:https://github.com/xiajingren/IdentityServer4-4.x-Scope-Demo

- END -

如果本文对您有用,

不妨点个“在”或者转发朋友圈支持一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Swagger2]配置Swagger

配置Swaggr 1、Swagger实例Bean是Docket&#xff0c;所以通过配置Docket实例来配置Swaggger。 package com.xxxx.swagger2.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.doc…

.Net Core微服务入门全纪录(完结)——Ocelot与Swagger

点击上方蓝字"小黑在哪里"关注我吧前言上一篇【.Net Core微服务入门全纪录&#xff08;八&#xff09;——Docker Compose与容器网络】完成了docker-compose.yml文件的编写&#xff0c;最后使用docker compose的一个up指令即可在docker中运行整个复杂的环境。本篇简单…

[Swagger2]Swaggr配置扫描接口配置Swagger开关

Swagger配置扫描接口 1、构建Docket时通过select()方法配置怎么扫描接口。 Bean public Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()// 通过.select()方法&#xff0c;去配置扫描接口,RequestHandlerSelectors配置如何扫描…

最全.Net学习资料库上线,今日可免费下载各类资源!(附百度云链接)

送资料送资料1 适合学习者&#xff1a;0-10年.Net开发人员2 更新时间&#xff1a;2020年7月24日3 在哪领取&#xff1a;文末扫码免费领取4 包含课程&#xff1a;零基础就业必修/高级开发必修/架构师必修5 配套资料&#xff1a;视频配套源码/最新面试题合集/最新技术书/安装包你…

[Swagger2]拓展:其他皮肤

拓展&#xff1a;其他皮肤 我们可以导入不同的包实现不同的皮肤定义&#xff1a; 1、默认的 访问 http://localhost:8080/swagger-ui.html <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><ve…

如何基于 DDD 构建微服务?

本文将讨论微服务与 DDD 涉及到的概念、策划和设计方法&#xff0c;并且尝试将一个单体应用拆分成多个基于 DDD 的微服务。微服务的定义微服务中的“微”虽然表示服务的规模&#xff0c;但它并不是使应用程序成为微服务的唯一标准。当团队转向基于微服务的架构时&#xff0c;他…

.NET Core ResponseCache【缓存篇(一)】

一、前言源码1、最近一直在看项目性能优化方式&#xff0c;俗话说的好项目优化第一步那当然是添加缓存&#xff0c;我们的项目之所以卡的和鬼一样&#xff0c;要么就是你的代码循环查询数据库&#xff08;这个之前在我们的项目中经常出现&#xff0c;现在慢慢在修正&#xff09…

[Swagger2]分组和接口注释及小结

分组和接口注释及小结 配置API分组 1、如果没有配置分组&#xff0c;默认是default。通过groupName()方法即可配置分组&#xff1a; Bean public Docket docket(Environment environment) {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(&qu…

Asp.Net Core 中的“虚拟目录”

写在前面现在部署Asp.Net Core应用已经不再限制于Windows的IIS上&#xff0c;更多的是Docker容器、各种反向代理来部署。也有少部分用IIS部署的&#xff0c;IIS部署确实是又快又简单&#xff0c;图形化操作三下五除二就可以发布好一个系统了。在过去Asp.Net MVC 项目部署的时候…

[mybatis]缓存_缓存有关的设置以及属性

缓存有关的设置以及属性 全局配置中的设置 和缓存有关的设置/属性1.cacheEnabletrue&#xff1b;false&#xff1b;关闭缓存(二级缓存关闭)(一级缓存一直可用的)2.每个select标签都有useCache“true”&#xff1b; false&#xff1b;不使用缓存(一级缓存依然使用&#xff0c;二…

EF批量插入太慢?那是你的姿势不对

大概所有的程序员应该都接触过批量插入的场景&#xff0c;我也相信任何的程序员都能写出可正常运行的批量插入的代码。但怎样实现一个高效、快速插入的批量插入功能呢&#xff1f;由于每个人的工作履历&#xff0c;工作年限的不同&#xff0c;在实现这样的一个需求时&#xff0…

[RabbitMQ]什么是MQ

什么是MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff0c;MQ 是一种非常…

.NET Core 实现基于Websocket的在线聊天室

什么是Websocket我们在传统的客户端程序要实现实时双工通讯第一想到的技术就是socket通讯&#xff0c;但是在web体系是用不了socket通讯技术的&#xff0c;因为http被设计成无状态&#xff0c;每次跟服务器通讯完成后就会断开连接。在没有websocket之前web系统如果要做双工通讯…

用 Natasha 写个类型调用的架子

一、想法自上篇文章&#xff0c;我一直琢磨整个好点的例子来展示 Natasha 动态编程能力, 于是就写了一个简单的类型调用的架子&#xff0c;耗时40分钟左右, 项目地址&#xff1a;https://github.com/NMSAzulX/TypeCaller二、功能特点a)、简单的注入功能支持无参构造注入支持递…

Natasha v4.0.0.0 动态编程新篇章

一、简介Natasha 基于 Roslyn 的 C# 动态程序集构建库&#xff0c;该库允许开发者在运行时使用 C# 代码构建域 / 程序集 / 类 / 结构体 / 枚举 / 接口 / 方法等&#xff0c;使得程序在运行的时候可以增加新的模块及功能。Natasha 集成了域管理/插件管理&#xff0c;可以实现域隔…

[RabbitMQ]RabbitMQ概念_四大核心概念

RabbitMQ RabbitMQ 的概念 RabbitMQ 是一个消息中间件&#xff1a;它接受并转发消息。你可以把它当做一个快递站点&#xff0c;当你要发送一个包裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按照这种逻辑 RabbitMQ …

.Net Core in Docker极简入门(下篇)

点击上方蓝字"小黑在哪里"关注我吧Docker-Compose代码修改yml fileup & down镜像仓库前言上一篇【.Net Core in Docker极简入门&#xff08;上篇&#xff09;】讲解了docker的一些基本命令和操作&#xff0c;并成功构建了自己的asp.net core web应用的镜像&#…

这么多Apache顶级项目,SkyWalking为何一枝独秀?

吴晟读完需要5分钟速读仅需 2 分钟吴晟Apache基金会会员&#xff0c;Apache SkyWalking创始人、项目VP和PMC成员&#xff0c;Apache孵化器PMC成员&#xff0c;Apache ShardingSphere PMC成员&#xff0c;Apache APISIX (incubating) PPMC成员&#xff0c;Apache ECharts (incub…

[RabbitMQ]工作原理_原理名词解释

RabbitMQ 核心部分 各个名词介绍 RabbitMQ工作原理 Broker&#xff1a; 接收和分发消息的应用&#xff0c;RabbitMQ Server 就是 Message Broker Virtual host&#xff1a; 出于多租户和安全因素设计的&#xff0c;把 AMQP 的基本组件划分到一个虚拟的分组中&#xff0c;类…

Istio 中的授权策略详解

本文节选自 ServiceMesher 社区出品的开源电子书《Istio Handbook——Istio 服务网格进阶实践》&#xff0c;阅读地址&#xff1a;https://www.servicemesher.com/istio-handbook/授权功能是 Istio 中安全体系的一个重要组成部分&#xff0c;它用来实现访问控制的功能&#xff…