IdentityServer4之Implicit和纯前端好像很配哦

前言

上一篇Resource Owner Password Credentials模式虽然有用户参与,但对于非信任的第三方的来说,使用这种模式是有风险的,所以相对用的不多;这里接着说说implicit隐式模式,这种模式比较适合于纯前端客户端,比如Vue、Angular、React项目等,相对来说整个流程比较安全,只需在认证服务器进行认证即可,无需在客户端进行相关隐私信息录入,但前提是要客户端保证安全,不然容易被别人钓鱼(安全很重要),那IdentityServer4不背这个锅。

正文

既然有用户参与,交互肯定少不了,认证那更不能缺少,所以这里使用OIDC(OpenID Connect)的协议进行用户身份验证;别跑,不管是客户端还是认证服务器端,已经都封装好了,拿过来直接用即可;

从流程先了解一下,直接上图:

流程简要说明:

  1. 用户通过浏览器(User-Agent)访问第三方客户端(Client);

  2. 如果客户端需要进行认证授权,则将其重定向到认证服务器(Authorization server);

  3. 用户(ResorceOwner)在认证服务器上进行认证;

  4. 认证服务器(Authorization server)验证成功之后,返回AccessToken和Id Token客户端;

  5. 后续用户再操作客户端的时候,若需访问保护资源,直接在请求中带上AccessToken即可;

  6. 最终资源服务器(Resource server)返回对应信息;

术语解释:

  • User-Agent:这里指就是浏览器;如果客户端是Web,就需要用户通过浏览器访问客户端,所以这里的浏览器就是User-Agent;

  • Id Token:标识用户身份的Token,这是OpenID Connect带上的。

知道大概的流程,接下来就通过代码实践的方式演示一把。

1.拷贝上一节Reource Owner Password的授权服务器和资源服务器代码并完善;

对于资源服务器来说,这里先暂时不用修改其他;

认证服务器增加界面支持

而认证服务器需要有自己的页面,因为在访问客户端时会重定向到认证服务器进行认证信息录入和授权相关操作,那页面需要自己写吗,不需要的,IdentityServer4模板中已经准备好了,如下操作:

  • 方式一:直接从github上下载,下载地址:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/tree/main;

  • 方式二:命令行方式,从IdentityServer4模板中获取;

    dotnet new -i IdentityServer4.Templates ##先安装模板,里面有很多关于IDS4的模板
    dotnet new is4ui ## 指定UI模板获取,
    

通过以上两种方式都可以获取到以下文件,将其拷贝到认证服务器项目中,如下:

由于之前的认证服务器只是单纯API项目,不支持MVC,因为增加的界面是MVC页面,所以需要在Startup.cs中增加MVC的支持,页面中需要样式文件的加载,则同时需要增加静态文件处理,如下:

运行起来看效果,如下:

备案客户端

上面界面没问题了,这里打算做一个纯前端(Vue)的客户端进行测试,所以需要在认证服务器中提前将客户端进行备案,如下:

2. 增加纯前端客户端(Vue)

这里不打算使用脚手架工具去生成项目,为了不喧宾夺主,这里就很单纯的写html和Js,只是在其中引用Vue,用Vue的思路进行编码演示;

既然是个纯前端项目,得要有个服务器作为宿主,然后通过URL地址访问页面,这里不想用其他比较重的服务器,live-server简单好用,就用它了,简单搭建一下环境:

环境准备

我是用npm安装,所以需要安装nodejs,这里就不详细扩展了,具体安装步骤详见:https://www.runoob.com/nodejs/nodejs-install-setup.html;

有了nodejs环境,直接npm安装live-server,如下命令:

npm install -g live-server ###全局安装live-server,后续都可以用

安装完就可以直接使用了,直接在指定目录下执行live-server即可,默认端口是8080;

创建纯前端客户端

项目目录结构如下:

简要说明:

  • js目录:存放依赖的js;

    live-server-https目录是提供live-server启动时提供live-server-https支持,其实项目本身并不需要;后续如果需要将前端页面指定https访问,可以指定此库运行;

    oidc-client.js/oidc-client.min.js是用于前端客户端实现OpenID Connect,引入直接使用即可,也可以自行在网上下载(https://github.com/IdentityModel/oidc-client-js);

    vue.js提供vue的支持,虽然没用脚手架,但用vue还是没问题;

  • callback.html登录成功之后回调的页面,即当在认证服务器登录成功之后重定向客户端的页面;

  • index.html主页面,这里也用于登出时重定向的页面;

  • noauth.html无权限时跳转的页面;

代码主要集中在index.html,下面直接上代码吧,具体说明直接看注释吧;

index.html代码

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title></title>
</head>
<body><div id="app"><button id="login" @click="login">Login</button><button id="api" @click="callApi">Call API</button><button id="logout" @click="logout">Logout</button><!-- 显示日志,包含登入、登出和请求API结果 --><pre id="results">{{results}}</pre></div><script src="./js/oidc-client.js"></script><script src="js/vue.js"></script><!-- <script src="./js/app.js"></script> --><script>var vm = new Vue({el: "#app",created() {// 根据配置信息创建用户管理对象,后续直接使用this.mgr = new Oidc.UserManager(this.config);},mounted() {// 这里要注意this的使用var that = this;this.mgr.getUser().then(function(user) {if (user) { // 判断是否登录成功that.log("User logged in", user.profile);} else { // 没登录that.log("User not logged in");}});},data: {// 客户端配置config: {authority: "http://localhost:6100",client_id: "JsClient",redirect_uri: "http://localhost:8080/callback.html",response_type: "id_token token",scope: "openid profile orderApi", //客户端需要的权限范围 post_logout_redirect_uri: "http://localhost:8080/index.html",},mgr: null, //登录对象results: "" //登录通过数据},methods: {// 登录login: function() {console.log("login");this.mgr.signinRedirect();},callApi: function() {console.log("CallAPI");var that = this;// 先判断是否登录,登录之后在去调用APIthis.mgr.getUser().then(function(user) {var url = "http://localhost:5000/api/Order";// 这里使用原生异步请求,就是引入第三方ajax库啦var xhr = new XMLHttpRequest();xhr.open("GET", url);xhr.onload = function() {// 显示请求API获取到的数据that.log(xhr.status, JSON.parse(xhr.responseText));};xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);// 发送请求xhr.send();});},logout: function() {console.log("logout");// 登出this.mgr.signoutRedirect();},// 将信息展示log: function() {var that = this;Array.prototype.forEach.call(arguments, function(msg) {if (msg instanceof Error) {msg = "Error: " + msg.message;} else if (typeof msg !== 'string') {msg = JSON.stringify(msg, null, 2);}that.results = msg + '\r\n';});}}});</script>
</body>
</html>

callback.html代码

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title></title>
</head>
<body><script src="./js/oidc-client.js"></script><script>new Oidc.UserManager().signinRedirectCallback().then(function() {console.log("test");// 如果登录成功就回到主页面window.location = "index.html";}).catch(function(e) {console.log(e);//没有权限就跳转到无权限页面window.location="noauth.html";});</script>
</body>
</html>

noauth.html代码

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title></title>
</head>
<body><div>没权限</div>
</body>
</html>

到这客户端的代码已经撸完了,直接进入JsClient目录,执行live-server即可:

如果使用http请求,执行live-server即可;

3.联合调试看效果

上一步已经将客户端启起来了,接下来把认证服务器和API资源服务器启动,看看效果:

  1. 点击Login进行登录,就会跳转到认证服务器进行验证,如下:


    到这一步,估计用其他浏览器没什么问题,会继续进行跳转;但如果用到谷歌最新的浏览器,这里就不会跳转,因为谷歌对Cookie进行整改,尽管输入正确的用户名和密码,也只是刷新一下,还是在登录页面,需要做一下处理,如下:

    新增一个处理类:SameSiteCookiesServiceCollectionExtensions.cs,代码内容就不贴啦,这是公开代码,大佬写好的解决方案;

    写好处理类之后,直接使用即可,如下:


    完成以上步骤,谷歌不能跳转的问题就解决啦; 继续往下走;

  2. 输入用户名和密码  Zoe/123456,点击登录,直接进入授权选择页面,如下:


    这个界面是不是比较熟,通常我们用微信、QQ或者是其他登录时,都会弹出一个授权页面选择授权内容。这个授权页面是可以控制不显示的,只需要在认证服务器备案客户端时设置属性即可,如下:


  3. 点击授权完成之后,就会重定向配置的callback.html页面,在callback.html代码中可以看到,如果判断用户已经登录,就直接转到index.html主页面,否则就转到noauth.html无权限页面,这里已经登录授权成功,肯定最终就转到index.html页面,如下:


  4. 点击CallAPI去调用受保护资源,内部是根据上一步得到AccessToken进行保护资源的访问;

    注意,这里资源服务器一定要进跨域配置,允许客户访问,在API资源服务器中进行如下配置:

    然后运行效果如下:

    image-20210128165434044

  5. 点击Logout登出,这里不截图了,小伙伴试试;

好吧,今天状态不佳,先到这,后续项目实战再好好说说。

源码地址:https://github.com/zyq025/IDS4Demo/tree/main/ImlicitDemo;

总结

Implicit模式使用思路差不多就是这样,但这种模式特别要注意项目本身安全,如数据传输过程被拦截,或网站本身容易被攻击,黑客通过钓鱼页面就容易获取隐私信息等,所以项目通常都强烈推荐https,降低数据传输过程被抓包的风险;而对于钓鱼等这种攻击,可以通过判断校验源IP等方式;安全的点很多,这里只是简单举例;下次说说Authorization Code(授权码)模式;

一个被程序搞丑的帅小伙,关注"Code综艺圈",跟我一起学~

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

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

相关文章

libaio.so.1 mysql_libaio.so.1()(64bit) is needed by MySQL-server

从官网下的mysql5.5的server&#xff0c;系统是centos 6.4x86_64,安装时一直报错&#xff1a;[rootdbserver opt]# rpm -ivh MySQL-server-5.5.31-2.el6.x86_64.rpmerror: Failed dependencies:libaio.so.1()(64bit) is needed by MySQL-server-5.5.31-2.el6.x86_64libaio.so.1…

docker 安装kafka_laradock 中如何安装 Laravel Dusk

laradock 中如何安装 Laravel Dusk&#xff1f;导语在本地安装 Laravel Dusk 一直失败&#xff0c;查了文档才发现在 laradock 中并不是只需要 composer require 就可以的&#xff0c;还有其他配置。下面记录一下。配置 laradock1.切换到 laradock 目录中&#xff0c;将 worksp…

.NET 中依赖注入组件 Autofac 的性能漫聊

Autofac 是一款超赞的 .NET IoC 容器 &#xff0c;在众多性能测评中&#xff0c;它也是表现最优秀的一个。它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改。它的实现方式是将常规的.net类当做 组件 处理。简单的性能测试在 LINQPad 中&…

SQLServer事务的隔离级别

事务的隔离级别SQL Server通过在锁资源上使用不同类型的锁来隔离事务。为了开发安全的事务&#xff0c;定义事务内容以及应在何种情况下回滚至关重要&#xff0c;定义如何以及在多长时间内在事务中保持锁定也同等重要。这由隔离级别决定。应用不同的隔离级别&#xff0c;SQL Se…

c语言 extern_Visual C++ 6.0环境中C语言extern 变量使用过程报错

extern 变量称为外部存储变量。extern声明了程序中将要用到但尚未定义的外部变量。本次错误的解决方法同样适用于外部函数。外部函数就是可以被其他源文件调用的函数&#xff0c;定义外部函数时使用extern进行修饰。首先&#xff0c;分别创建两个源文件“ex1.c”和“ex2.c”。其…

怎么删除mysql的所有文件内容_mysql删除全部数据库

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里云数据库专家保驾护航&#xff0c;为用户…

盘点大厂的那些开源项目 - 华为

HarmonyOS鸿蒙系统&#xff08;HarmonyOS&#xff09;&#xff0c;是第一款基于微内核的全场景分布式OS&#xff0c;是华为自主研发的操作系统。华为会率先部署在智慧屏、车载终端、穿戴等智能终端上&#xff0c;未来会有越来越多的智能设备使用开源的鸿蒙OS。鸿蒙 OS 底层由鸿…

SAP项目文档 清单 考核标准

SAP项目文档的考核标准项目启动阶段 项目计划及对计划的调整 建议&#xff1a; 1、 对项目进度进行分类&#xff0c;定义每个阶段的关键任务。 2、 对每个阶段应形成的文档进行说明&#xff0c;哪类文档由谁制作&#xff0c;由谁签核必须做出统一的规定。最好能提供每类文档的标…

详解C#break ,continue, return

C#编程语法中break ,continue, return这三个常用的关键字的学习对于我们编程开发是十分有用的&#xff0c;那么本文就向你介绍break ,continue, return具体的语法规范。C#编程语法中我们会碰到break ,continue, return这三个常用的关键字&#xff0c;那么关于这三个关键字的使用…

ubuntu mysql怎么备份_Ubuntu下MySQL备份与异地备份

下面是一则MySQL备份实例&#xff0c;在Ubuntu下测试通过。完成任务是本地备份。可用于服务器端。#! /bin/bashecho "backupmysql V1.0"###date stamp###datestamp$(date %Y-%m-%d)###path ###startdir/home/user/mysqlbackup###bakfile prefix###fileprefixsqlecho …

TC字符界面-菜单程序【原创】

TC字符界面-菜单程序【原创】2008/03/06 22:58/*本程序代码属本人原创&#xff0c;未经允许不得转载&#xff0c;谢谢合作作者&#xff1a;HungryAnt发布时间&#xff1a;2008-3-6*//*快捷键功能没有提供,因为程序有各自的快捷键*/#include<stdio.h>#include<conio.h&…

java 位运算_java学习之运算符与表达式(四)

(6)位运算符位运算是指对整数按二进制的位进行运算。位运算用于整数或字符类型。有7个&#xff1a;~(非)、&(与)、&#xff5c;(或)、^(异或)、<>(右移)、>>>(无符号右移)。例&#xff1a;以byte类型4为例。byte类型占用1个字节。4的二进制为&#xff1a;00…

【Http】一文备忘Http状态码(406,415,422)

最近在调试接口时&#xff0c;web api 报了一个415状态码。好久没见到这个状态码&#xff0c;一时还真不知道啥情况。所以&#xff0c;人的大脑是有遗忘规律的&#xff0c;为了加深印象&#xff0c;所以我觉得我有必要再复习一下。1.HTTP的状态码 首先复习一下所有的状态码。1x…

mysql innodb 多线程插入_mysql innodb 并发插入问题,包大量死锁错误

开了10个并发写线程&#xff0c;没1000条记录批量提交一次&#xff0c;结果mysql包大量死锁错误&#xff01;"Deadlock found when trying to get lock; try restarting transaction"引擎用的是Innodb 主键字段是auto_increament.mysql 有这么脆弱吗&#xff1f;crea…

什么是SEO策略呢

从2005年后&#xff0c;我基本都只是给大型网站做SEO&#xff0c;因为给大型网站做SEO&#xff0c;效果非常的明显&#xff0c;价格自然也可以收的非常高。总结这两年来我做过的几十家大型网站的SEO经验&#xff0c;我发现&#xff0c;SEO策略是最为重要的。什么是SEO策略呢&am…

infor wms 项目启动_广汽本田增城工厂No.2L WMS项目正式启动

Warehouse导读&#xff1a;近日&#xff0c;在生管科No.2L办公室&#xff0c;广汽本田增城工厂No.2L WMS项目启动大会如期召开。生产管理科&#xff0c;IT科&#xff0c;FNL以及汉得信息有限公司的WMS项目组成员参加了本次启动大会。Management2018年10月&#xff0c;生管科已经…

mysql动态扩展_动态可扩展查询MYSQL5.7JSON+虚拟列+Mybatis

背景&#xff1a;现有业务扩展字段&#xff0c;都存在feature字段&#xff0c;存在语义不清晰以及&#xff0c;难以利用索引查询问题Mysql 5.7后推出利器&#xff0c;JSON虚拟列&#xff0c;即实现了业务语义统一&#xff0c;也支持索引查询加速一、简单描述MySQL 5.7.7 labs版…

asp.net core安全事项(中)

上传文件上传文件是造成风险的很大因素&#xff0c;所以对上传文件进行处理是重要的&#xff0c;首先要处理的是&#xff1a;a、上传文件大小限制&#xff1b;b、上传文件类型(能过扩展或&#xff0c;或文件头)限制&#xff1b;c、上传的名称要替换掉&#xff1b;d、上传的文件…

TCL:花开刹那还是浴火重生

TCL&#xff1a;花开刹那还是浴火重生 [url]http://www.sina.com.cn[/url] 2008年04月07日 15:24 民营经济报本报记者 叶键 TCL3月份公布了2007年财报&#xff0c;公司净利润达3.9亿元&#xff0c;并于3月27日“摘星脱帽”&#xff0c;恢复为“TCL集团”的自由身&#xff0c;…

http referer 验证防御方法_渗透测试 跨站攻击防御与安全检测手法剖析

上一节讲到了渗透测试中xss跨站攻击检测方法和防护,这一节也是关于跨站攻击的另一个手法CSRF&#xff0c;很多客户找到我们想要了解更多的跨站攻击检测方法以及防御此类攻击的办法,想要让网站的安全性更加坚固,对此提醒大家渗透测试网站必须要拿到授权才能测试哦&#xff01;3.…