从Client应用场景介绍IdentityServer4(一)

从Client应用场景介绍IdentityServer4(一)
原文:从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客户端的应用。

文中如有错漏,欢迎指正,将对此系列文章进行维护。

posted on 2018-12-26 22:30 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10182274.html

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

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

相关文章

开发常用代码笔记

Vue 使用moment插件对时间进行格式化&#xff08;全局设置&#xff09; 下载插件 npm install moment --save 在main.js中引入插件 import moment from ‘moment’ 在main.js中定义全局过滤器 Vue.filter(dataFilter,function (dataStr,patten YYYY-MM-DD HH:mm:ss) {retur…

微信小程序——账号及开发工具

1. 注册微信小程序账号 点击我进入微信公众平台 进入后点击立即注册 注册成功且登录后进入小程序管理后台 2. 安装开发者工具 点击进入开发文档 进入安装开发工具&#xff08;稳定版本&#xff09; 一路默认下一步进行安装 3. 开发者工具的使用 使用注册微信小程序的微信号…

CSS注意的地方

content-box和border-box的区别 2018年02月27日 22:20:16 sulingliang 阅读数&#xff1a;8011盒子模型 盒子宽度&#xff1a;paddingbordercontent-width 盒子高度&#xff1a;paddingbordercontent-height 如图所示 盒子模型content-box 说明&#xff1a;在内容宽度和高度之…

机器学习笔记(6) 线性回归

先从最简单的例子开始,假设我们有一组样本(如下图的一个个黑色的圆点),只有一个特征,如下图,横轴是特征值,纵轴是label。比如横轴是房屋面积,纵轴是房屋价格. 现在我们要做什么呢&#xff1f;我们试图找到一条直线yaxb,可以尽量好的拟合这些点. 你可能要问了,为啥是直线,不是曲…

仿微信朋友圈项目梳理

项目功能简介&#xff1a; 用户通过手机号验证码进行登录和注册 可以浏览动态列表中的所有动态 登录成功后用户可以发表自己的动态 也可以对自己认可欣赏的动态进行点赞和评论 也可以通过动态结识志同道合的朋友 进行聊天和探讨 前端&#xff1a;采用Vue框架搭建 weui进行页面…

echarts鼠标事件以及自定义数据获取

事件添加方法&#xff1a; 对应官网位置&#xff1a;https://www.echartsjs.com/api.html#events 鼠标事件包括 click、dblclick、mousedown、mousemove、mouseup、mouseover、mouseout、globalout、contextmenu。 myChart.on(click, function (params) {console.log(params); …

[数学]点、线、面分割问题

平面分割问题 p条直线相交于一点时&#xff0c;分割的图形有 2*(n-1) 个&#xff0c;此时再加一条直线&#xff0c;在 2*(n-1) 的基础上再加 n条&#xff0c;此时为2*n n条曲线&#xff0c;其中有m条相交于一点&#xff0c;每两个曲线都交于两点 平面上有n条直线&#xff0c;且…

移动开发

1.移动端基础 1.1 浏览器现状 PC端浏览器 360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器&#xff08;停止服务&#xff09;、搜狗浏览器、IE浏览器 移动端浏览器 UC、QQ浏览器、欧朋浏览器、百度手机浏览器、360、搜狗、猎豹、谷歌等其他手机自带的浏览器 国…

Django之路由系统

Django的路由系统 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。 你就是以这种方式告诉Django&#xff0c;对于这个URL调用这段代码&#xff0c;对于那个URL调用那段代码。 URLconf配置…

微信小程序——操作数据库

案例一&#xff1a;统计用户的访问次数 业务需求&#xff1a; 统计每个用户对程序的访问次数将访问次数存储到数据库中访问次数应该与用户进行关联 业务逻辑&#xff1a; 如果用户是第一次访问此程序&#xff0c;向数据库添加一条记录&#xff1a;{openid&#xff1a;45454…

shop--12.阿里云部署以及域名绑定

一、申请阿里云服务器&#xff08;1&#xff09;PC访问阿里云https://www.aliyun.com/&#xff0c;申请阿里云帐号&#xff08;可以用您的支付宝帐号登录&#xff0c;因为支付宝帐号已经进行了实名认证&#xff0c;使用起来更方便&#xff09;并登录&#xff08;2&#xff09;找…

微信小程序——获取用户的运动步数

程序获取用户信息步骤 点击参考微信文档中的授权首先程序先向用户申请访问哪些权限用户做出选择后返回给程序程序携带权限访问服务器如果用户允许则返回信息如果用户为允许则不返回 自定义函数getUserRun 为获取用户的微信运动数据 页面加载调用此函数函数中执行下面操作 1…

第一次个人作业

该作业所属课程&#xff1a;https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2作业要求地址&#xff1a;https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2/homework/3340团队名称&#xff1a;脑壳痛 作业的目标 1.通过测试其他组的软件项目学习其…

微信小程序——解决上传并部署云函数时报错ResourceNotFound.Function, 未找到函数版本,请创建后再试。 (7f2d9d2d-5eac-4575-9n57-acd66cfa587g

1. 上传部署我们的云函数 2. 报错 错误信息为&#xff1a;Error: ResourceNotFound.Function, 未找到函数版本&#xff0c;请创建后再试。 (7f2d9d2d-5eac-4575-9b57-acd66cfa587e) 3. 原因 原因是可能我们在调试的时候不小心将我们开发控制台中的云函数删除了 4. 解决办法…

【IT界的厨子】酱香鲈鱼

食材: 前世曾经回眸的鲈鱼一条(主要选刺少的鱼&#xff0c;适合孩子吃&#xff0c;大人吃随意&#xff0c;草鱼比较大) 五花肉少许(肥一些的) 豆腐 辅料: 葱姜 蒜(选) 大料 香菜 调味: 啤酒(两罐) 黄豆酱或豆瓣酱(选) 老抽 生抽 料酒 盐 步骤: 1、鱼肉划开&#xff0c;方便炖的…

for each....in、for in、for of

一、一般的遍历数组的方法: var array [1,2,3,4,5,6,7]; for (var i 0; i < array.length; i) { console.log(i,array[i]); } 二、用for in的方遍历数组 for(let index in array) { console.log(index,array[index]); }; 三、forEach array.forEach(v>{ cons…

Vue cli3.0创建Vue项目

创建Vue项目 在要创建项目的文件夹下面打开Powershell窗口 输入命令 vue create 项目名称 选择第二项 回车后 选择是否使用历史路由 no 回车 选择 Less 回车 选择第三个 回车 选择第一个 回车 选择第一个 回车 是否保存模板 选择no 完成啦 完成

Remote desktop manager共享账号

因为多个远程机器&#xff0c;是会用了域账号进行登录的。而域账号的密码&#xff0c;三个月之后&#xff0c;密码强制过期 添加一个新的entry&#xff0c;类型是Credential Entry&#xff0c;然后选择用户名/密码 在remote desktop编辑的页面&#xff0c;Credentials选择Crede…

Mui常用的方法

中对话框 语法&#xff1a;mui.confirm 用法 mui.confirm("确认要切换角色&#xff1f;", "提示", btnArray, function(e) {if(e.index 1) {} else {}});组件名作用alert警告框confirm确认框prompt输入对话框toast消息提示框&#xff08;自动消失&#x…

java ListMapString,Object遍历的方法

java List<Map<String,Object>遍历的方法 public class Test {public static void main(String[] args) {List<Map<String, Object>> listMaps new ArrayList<Map<String, Object>>();Map<String, Object> map1 new HashMap<Strin…