从Client应用场景介绍IdentityServer4(一)
一、背景
IdentityServer4的介绍将不再叙述,百度下可以找到,且官网的快速入门例子也有翻译的版本。这里主要从Client应用场景方面介绍对IdentityServer4的应用。
首先简要介绍ID Token和Access Token:
Access Token是授权第三方客户端访问受保护资源的令牌。 ID Token是第三方客户端标识用户身份认证的问令牌,是JSON Web Token格式。
二、Client应用场景介绍
Client类是为OpenID Connect或OAuth 2.0 协议建模的。
我们先看官网快速入门中给的Client例子
public static IEnumerable<Client> GetClients(){// client credentials clientreturn new List<Client>{new Client{ClientId = "Client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets ={new Secret("secret".Sha256())},AllowedScopes = { "api1" }},// resource owner password grant clientnew Client{ClientId = "ro.client",AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,ClientSecrets = {new Secret("secret".Sha256())},AllowedScopes = { "api1" } },// OpenID Connect hybrid flow and client credentials client (MVC)new Client{ClientId = "mvc",ClientName = "MVC Client",AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,ClientSecrets ={new Secret("secret".Sha256())},RedirectUris = { "http://localhost:5002/signin-oidc" },PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"api1"},AllowOfflineAccess = true},// JavaScript Clientnew Client{ClientId = "js",ClientName = "JavaScript Client",AllowedGrantTypes = GrantTypes.Implicit,AllowAccessTokensViaBrowser = true,RedirectUris = { "http://localhost:5003/callback.html" },PostLogoutRedirectUris = { "http://localhost:5003/index.html" },AllowedCorsOrigins = { "http://localhost:5003" },AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"api1"},}};}
里面主要介绍四种Client应用场景。
(1)客户端模式(AllowedGrantTypes = GrantTypes.ClientCredentials)
这是一种最简单的授权方式,应用于服务于服务之间的通信,token通常代表的是客户端的请求,而不是用户。
使用这种授权类型,会向token endpoint发送token请求,并获得代表客户机的access token。客户端通常必须使用token endpoint的Client ID和secret进行身份验证。
适用场景:用于和用户无关,服务与服务之间直接交互访问资源
(2)密码模式(ClientAllowedGrantTypes = GrantTypes.ResourceOwnerPassword)
该方式发送用户名和密码到token endpoint,向资源服务器请求令牌。这是一种“非交互式”授权方法。
官网上称,为了解决一些历史遗留的应用场景,所以保留了这种授权方式,但不建议使用。
适用场景:用于当前的APP是专门为服务端设计的情况。
(3)混合模式和客户端模式(ClientAllowedGrantTypes =GrantTypes.HybridAndClientCredentials)
ClientCredentials授权方式在第一种应用场景已经介绍了,这里主要介绍Hybrid授权方式。Hybrid是由Implicit和Authorization code结合起来的一种授权方式。其中Implicit用于身份认证,ID token被传输到浏览器并在浏览器进行验证;而Authorization code使用反向通道检索token和刷新token。
推荐适用Hybrid模式。
适用场景:用于MVC框架,服务器端 Web 应用程序和原生桌面/移动应用程序。
(4)简化模式(ClientAllowedGrantTypes =GrantTypes.Implicit)
Implicit要么仅用于服务端和JavaScript应用程序端进行身份认证,要么用于身份身份验证和access token的传输。
在Implicit中,所有token都通过浏览器传输的。
适用场景:JavaScript应用程序。
三、Server端搭建
为了介绍IdentityServer4的Client应用场景,我们需要先搭建IdentityServer服务端。
这里搭建的是使用EF Core来做数据操作,保存到SQL Server中。
(1)新建API项目
(2)安装IdentityServer4.EntityFramework包
(3)安装IdentityServer4包
(4)右键项目的属性,编辑项目的.csproj文件
添加如下元素
<ItemGroup><DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /> </ItemGroup>
如图:
(5)cmd管理员身份进入项目目录路径(D:\IdentityServer4\Server),运行:dotnet ef
(6)项目内添加Config.cs类,代码如下
public class Config{public static List<TestUser> GetUsers(){return new List<TestUser>{new TestUser{SubjectId = "1",Username = "alice",Password = "password",Claims = new List<Claim>(){new Claim(JwtClaimTypes.Role,"superadmin") }},new TestUser{SubjectId = "2",Username = "bob",Password = "password",Claims = new List<Claim>{new Claim("name", "Bob"),new Claim("website", "https://bob.com")},}};}public static IEnumerable<Client> GetClients(){// client credentials clientreturn new List<Client>{new Client{ClientId = "Client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets ={new Secret("secret".Sha256())},AllowedScopes = { "api1" }},// resource owner password grant clientnew Client{ClientId = "ro.client",AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,ClientSecrets ={new Secret("secret".Sha256())},AllowedScopes = { "api1" }},// OpenID Connect hybrid flow and client credentials client (MVC)new Client{ClientId = "mvc",ClientName = "MVC Client",AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,ClientSecrets ={new Secret("secret".Sha256())},RedirectUris = { "http://localhost:5002/signin-oidc" },PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"api1"},AllowOfflineAccess = true},// JavaScript Clientnew Client{ClientId = "js",ClientName = "JavaScript Client",AllowedGrantTypes = GrantTypes.Implicit,AllowAccessTokensViaBrowser = true,RedirectUris = { "http://localhost:5003/callback.html" },PostLogoutRedirectUris = { "http://localhost:5003/index.html" },AllowedCorsOrigins = { "http://localhost:5003" },AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"api1"},}};}public static IEnumerable<IdentityResource> GetIdentityResources(){return new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),};}public static IEnumerable<ApiResource> GetApiResources(){return new List<ApiResource>{new ApiResource("api1", "My API")};}
添加引用:
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;
(7)编辑Startup.cs文件的ConfigureServices方法,改成如下代码。
public void ConfigureServices(IServiceCollection services){const string connectionString = @"Server=localhost;database=IdentityServer4;User ID=sa;Password=Pwd;trusted_connection=yes";var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;// configure identity server with in-memory stores, keys, clients and scopes services.AddIdentityServer().AddDeveloperSigningCredential().AddTestUsers(Config.GetUsers())// this adds the config data from DB (clients, resources).AddConfigurationStore(options =>{options.ConfigureDbContext = builder =>builder.UseSqlServer(connectionString,sql => sql.MigrationsAssembly(migrationsAssembly));})// this adds the operational data from DB (codes, tokens, consents).AddOperationalStore(options =>{options.ConfigureDbContext = builder =>builder.UseSqlServer(connectionString,sql => sql.MigrationsAssembly(migrationsAssembly));// this enables automatic token cleanup. this is optional.options.EnableTokenCleanup = false;//是否从数据库清楚令牌数据,默认为falseoptions.TokenCleanupInterval = 300;//令牌过期时间,默认为3600秒,一个小时 });//.AddInMemoryClients(Config.GetClients()); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
添加引用:
using Microsoft.EntityFrameworkCore;
using System.Reflection;
(8)cmd管理员身份进入到项目目录路径(D:\IdentityServer4\Server\Server),注意,多了一层目录,分别运行以下两条指令:
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDbdotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
运行完后,项目中会多了一个Data文件夹
(9)在Startup.cs中添加初始化数据库方法。
private void InitializeDatabase(IApplicationBuilder app) {using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()){serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();context.Database.Migrate();if (!context.Clients.Any()){foreach (var client in Config.GetClients()){context.Clients.Add(client.ToEntity());}context.SaveChanges();}if (!context.IdentityResources.Any()){foreach (var resource in Config.GetIdentityResources()){context.IdentityResources.Add(resource.ToEntity());}context.SaveChanges();}if (!context.ApiResources.Any()){foreach (var resource in Config.GetApiResources()){context.ApiResources.Add(resource.ToEntity());}context.SaveChanges();}} }
添加引用:
using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
(10)在Startup.cs中的Configure方法修改成以下代码。
public void Configure(IApplicationBuilder app, IHostingEnvironment env){//if (env.IsDevelopment())//{// app.UseDeveloperExceptionPage();//} InitializeDatabase(app);//app.UseMvc();}
到这里,把项目以控制台形式运行
点击运行,可以跑起来,且生成数据库IdentityServer4DB。
关于Client的说明可以查阅官网资料:https://identityserver4.readthedocs.io/en/release/reference/client.html
源码地址:https://github.com/Bingjian-Zhu/Server.git
服务端准备好之后,下篇文章开始介绍Client客户端的应用。
文中如有错漏,欢迎指正,将对此系列文章进行维护。
转载于:https://www.cnblogs.com/lonelyxmas/p/10182274.html
从Client应用场景介绍IdentityServer4(一)相关推荐
- 从Client应用场景介绍IdentityServer4(二)
从Client应用场景介绍IdentityServer4(二) 原文:从Client应用场景介绍IdentityServer4(二) 本节介绍Client的ClientCredentials客户端模式 ...
- python在日常工作处理中的应用-python在工作中的应用场景介绍
python在工作中的应用场景介绍 发布时间:2020-04-21 14:44:30 来源:亿速云 阅读:277 作者:小新 今天小编给大家分享的是python在工作中的应用场景介绍,相信很多人都不太 ...
- ARMS企业级场景被集成场景介绍
简介:ARMS企业级场景被集成场景介绍 通过本次最佳实践内容,您可以看到ARMS OpenAPI可以灵活的被集成到客户链路监控场景,并对其进行可视化图形展示监控信息. 1. 背景信息 应用实时监控服务 ...
- UE4学习-场景介绍、基本操作、快捷键
文章目录 场景介绍 坐标轴的操作 摄像机的基本操作 使用介绍 调整WASD移速 操作快捷键 · Unreal Engine 4 · 场景介绍 通过上一篇博文里面的步骤,已经把软件启动起来了. 然后创建 ...
- 基于实时计算Flink的机器学习算法平台及场景介绍
作者:高旸(吾与),阿里巴巴高级技术专家 1. 前言 随着互联网"人口红利"的"消耗殆尽",基于"T+1"或者离线计算的机器学习平台及推荐系 ...
- Redis八种数据类型及应用场景介绍
本文来说下Redis八种数据类型及应用场景介绍 文章目录 概述 String 介绍 应用场景 Hash 介绍 应用场景 List 介绍 应用场景 Set 介绍 应用场景 ZSet 介绍 应用场景 Bi ...
- (1)大数据和应用场景介绍
专栏目录 (1)大数据和应用场景介绍 (2)大数据技术综述总结 (3)HDFS原理与高可用技术原理介绍 (4)Yarn架构.资源管理原理和运维技术介绍 (5)Kafka原理和高可用介绍 1.大数据基本 ...
- WT588E语音芯片+数码管的应用场景介绍
前言: WT588E02B语音芯片是一款SPI通讯方式的语音芯片.最大的特点便是客户可以自行通过SPI协议,按照规定的数据更换流程发送语音数据,实现客户可以在线更新音频数据,有利于客户产品的升级迭代, ...
- 机器视觉系统图像采集卡功能特点及应用场景介绍
机器视觉系统图像采集卡功能特点及应用场景介绍 机器视觉技术是目前工业生产检测.医疗检测等领域为实现自动化.智能化而采取的应用.整个机器视觉系统分为图像采集与图像处理两大板块,采用模拟工业相机的图像采集 ...
最新文章
- 递增的整数序列链表的插入_每日算法题 | 剑指offer 链表专题 (5)链表中倒数第k个节点...
- 优化VS 2005编译,脱离漫长的等待!
- [恢]hdu 2047
- Name与x:Name的关系--转载
- 4.6 大数据集-机器学习笔记-斯坦福吴恩达教授
- Smartforms 在sap系统设置纸张打印格式
- java接口测试工具_这 5 款实用性能测试工具,你会如何选择?
- C/C++语言变量声明内存分配
- 为什么C语言仍然占据统治地位?
- .net登录界面_JAVA实现简单的用户登录客户端
- Git基本用法(一)
- 项目组合、项目集、项目管理实践经验及思考
- 毕设项目部署到服务器,在云服务器上做毕设
- 张小龙2019微信公开课演讲实录
- jOOQ 3.13.2 代码生成过程及解决 daos 无法生成的问题
- 深度学习之目标检测--Pytorch实战
- java二维码生成 使用SSM框架 搭建属于自己的APP二维码合成、解析、下载
- 计算机网络协议(二)——从二层到三层
- Vue项目History模式404问题解决
- 孪生素数问题——素数(质数)指的是不能被分解的数,除了1和它本身之外没有其他数能够整除。如果两个素数之差为2,则这两个素数就是孪生素数,例如3和5为孪生素数,。找出1-100之间的所有孪生素数。
热门文章
- HJ浇花(牛客竞赛 约束差分)
- 高并发图片实时渲染技术在阿里妈妈的大规模应用
- 为什么不建议学python贴吧_为什么那么多自学Python的后来都放弃了,总结下来就这些原因...
- go读取excel_Golang操作Excel
- 移动端h5 顶部菜单栏_HTML5 移动端上 动态固定菜单栏的问题
- 微软修复工具_微软正在推出更新以修复此前被发现的Windows 10 SFC问题
- android jar 反射,android 第三方jar库 反射得到自己的资源ID
- 思维导图一定要用计算机来完成吗,计算机绘制思维导图有什么优势
- python通过下载链接下载_Python根据URL地址下载文件——wget
- python3网络编程传输图片_python网络编程(图片传输)