前言

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

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

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

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

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

VS2019打开项目:

运行项目:

配置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模板:

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的Name
options.Audience = "api1";
//不使用https
options.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]标记:

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

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

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

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

ApiScope策略授权

继续修改代码。

Api1Resource项目NuGet安装:IdentityServer4.AccessTokenValidation

再新建一个TestController用于区分:

下面我需要做的是使用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的代码很简单:

因为修改了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:

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

再访问test,得到403错误:

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

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

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

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

总结

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

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

IdentityServer4 4.x版本 配置Scope的正确姿势的更多相关文章

  1. iOS的多版本配置(版本分离,多环境配置)

    前几天公司说一个客户要搞一个app,我说搞呗,跟我啥关系...他说,就是从咱的app上搞,什么都一样,就是一些logo啥的不一样.我一开始感觉,那就改改logo呗,后来一想,凑,百度推送,友盟统计,B ...

  2. 在Windows 7下面IIS7的安装和 配置ASP的正确方法

    在Windows 7下如何安装IIS7,以及IIS7在安装过程中的一些需要注意的设置,以及在IIS7下配置ASP的正确方法. 一.进入Windows 7的 控制面板,选择左侧的打开或关闭Windows ...

  3. Eclipse(非J2EE版本)配置Extjs环境以及安装部署Tomcat

    Eclipse(非J2EE版本)配置Extjs环境(Spket) 1. 安装spket插件,帮助->安装新软件->http://www.agpad.com/update. 2. 设置Spk ...

  4. Elasticsearch搜索引擎版本配置

    简要描述: 搜索引擎版本配置 产品 版本号 ES版本要求 说明 PHP =5.5.38     Java =1.8.0_73   用于支持ES Elasticsearch =2.3.5   搜索引擎 ...

  5. 【MYSQL】mysql-5.6.19-win32免安装版本配置方法

    [MYSQL]mysql-5.6.19-win32免安装版本配置方法 1.文件下载网站(http://dev.mysql.com/downloads/): 具体下载地址:http://211.136. ...

  6. XAMPP各个版本配置

    XAMPP各个版本配置 http://code.stephenmorley.org/articles/xampp-version-history-apache-mysql-php/ XAMPP  Ap ...

  7. Python在windows平台的多版本配置

    Python在windows平台的多版本配置 快速阅读: ​ python在windows平台的环境变量以及多版本配置 ,以及pycharm如何安装包,以及安装包出错时如何排查. 1.python环境 ...

  8. [ASP.NET Core 3框架揭秘] Options[1]: 配置选项的正确使用方式[上篇]

    依赖注入不仅是支撑整个ASP.NET Core框架的基石,也是开发ASP.NET Core应用采用的基本编程模式,所以依赖注入十分重要.依赖注入使我们可以将依赖的功能定义成服务,最终以一种松耦合的形式 ...

  9. [ASP.NET Core 3框架揭秘] Options[2]: 配置选项的正确使用方式[下篇]

    四.直接初始化Options对象 前面演示的几个实例具有一个共同的特征,即都采用配置系统来提供绑定Options对象的原始数据,实际上,Options框架具有一个完全独立的模型,可以称为Options ...

随机推荐

  1. Java实现 LeetCode 242 有效的字母异位词

    242. 有效的字母异位词 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = " ...

  2. Linux目录处理命令cd、pwd、rmdir、cp、mv、rm详解

    命令cd详解 命令cd(英文原意:change directory),命令路径及执行权限为: 可以看到它的路径为/usr/bin/cd,因此,它的执行权限是所有用户 基本功能是切换目录,例如:cd . ...

  3. webpack从单页面到多页面

    前言 从上次更完webpack从什么都不懂到入门之后,好久没有更新过文章了,可能是因为自己懒了吧.今天看了下自己的索引量少了一半o(╥﹏╥)o,发现事态严重,赶紧更新一篇23333 也是因为最近踩了一 ...

  4. c 到 c++

    目录:   1.引用相关   2.const关键字   3.动态内存分配 1.引用相关: /* 概念:某个变量的引用等价于这个变量的别名 格式:类型名 & 引用名 = 某变量名 作用: 1. ...

  5. Canvas绘制圆点线段

    最近一个小伙遇到一个需求,客户需要绘制圆点样式的线条. 大致效果是这样的: 思路一:计算并使用arc填充 他自己实现了一种思路,然后咨询我有没有更好的思路. 先看看他的思路是如何实现的,大致代码如下: ...

  6. vue踩过的坑('url' is assigned a value but never used no-unused-vars)

    1.代码编写 2.遇见错误 3.解决方案 在错误代码后加入注释:(// eslint-disable-line no-unused-vars) 之后页面上就不会出现该错误信息了

  7. test tt=0 <=>test(0)

    class test{ int mvalue; public: test(int i){ cout << "test(int i) =" << i < ...

  8. 关于Integer类的值使用==比较

    题记:前几天面试Java基础给来了个面试题Integer a=100,b=100;System.out.println(a==b); 当时回答是true,后来面试官又来了一个Integer a=200 ...

  9. 机器学习——手把手教你用Python实现回归树模型

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天这篇是机器学习专题的第24篇文章,我们来聊聊回归树模型. 所谓的回归树模型其实就是用树形模型来解决回归问题,树模型当中最经典的自然还是决 ...

  10. GatewayWorker与ThinkPHP等框架结合

    使用GatewayWorker时开发者最关心的是如何与现有mvc框架(ThinkPHP Yii laravel等)整合,以下是官方推荐的整合方式. 见示意图: ## 总体原则 现有mvc框架项目与Ga ...