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,一经查实,立即删除!

相关文章

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 中&…

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

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

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

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

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 …

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…

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、上传的文件…

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

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

如何手动连上mysql_如何手动安装MySql

想安装当然要先有一个MySql的安装包 这里使用的是mysql-5.7.12-winx64安装包百度云&#xff1a;http://pan.baidu.com/s/1kVAuXuv       密码&#xff1a;hr391.要将压缩包解压到你的指定位置(最好将要用的工具文件分类放好)例如&#xff1a;D:javaAppmysql-5.7.12-winx6…

WebRTC成为W3C和IETF正式标准

喜欢就关注我们吧&#xff01;2021年1月26日&#xff0c;W3C&#xff08;万维网联盟&#xff09;和 IETF &#xff08;互联网工程任务组&#xff09;同时宣布 WebRTC&#xff08;Web Real-Time Communications&#xff0c;Web 实时通信&#xff09;现发布为正式标准&#xff0c…

mysql非安装_mysql 非安装版的配置

一直以来都是使用wamp中集成的mysql数据库&#xff0c;今天突然想试试下载一个mysql的zip包进行配置。一、下载mysql非安装版下载地址可以到&#xff1a;http://dev.mysql.com/downloads/mysql/ &#xff0c;或者直接点击下载mysql-32bit&#xff1a;http://cdn.mysql.com/Down…

Xamarin.Forms: 无限滚动的ListView(懒加载方式)

说明 在本博客中&#xff0c;学习如何在Xamarin.Forms应用程序中设计一个可扩展的无限滚动的ListView。这个无限滚动函数在默认的Xamarin.Forms不存在&#xff0c;因此我们需要为此添加插件。在这里我们需要知道无限滚动时如何工作的。首先&#xff0c;显示固定的数据。一旦用户…

javaweb应用开发与实践pdf_基于阿里云打造「云原生」Web应用——「懒猪行」Web应用开发实践...

作者&#xff1a;阿里云MVP 刘远程背景『懒猪行』专注于境外自由行S2B业务&#xff0c;涉及分销、终端用户服务、供应链等多个服务环节&#xff0c;随着业务规模的不端增加&#xff0c;我们一直在探索Web应用开发的最佳实践&#xff0c;以加快Web应用的迭代效率&#xff0c;为B…

python大型项目中的日志模块_Python中日志模块的使用

前言程序和脚本往往是无人值守运行的&#xff0c;一旦发生问题&#xff0c;就需要我们去追溯当时的情况来定位问题的原因。这便需要我们在程序和脚本中引入日志的功能。相比于print信息&#xff0c;使用logging日志有以下优点可以记录输出日志的时间、文件、函数以及代码行&…

OSI强调:SSPL并不是开源许可证

喜欢就关注我们吧&#xff01;日前&#xff0c;开放源代码促进会 OSI&#xff08;Open Source Initiative&#xff09;强调&#xff0c;SSPL 并不是一个开源许可证。OSI 表示&#xff0c;SSPL&#xff08;Server Side Public License&#xff09; 是一种典型的 “fauxpen”&…

.NET Remoting

轉自:http://www.iiiedu.org.tw/knowledge/knowledge20030430_2.htm.NET Remoting 資策會數位教育研究所講師 董淑惠     概念簡介 微軟以往使用COM/DCOM的技術來處理分散式系統架構&#xff0c;透過Client端的Proxy代理程式來呼叫遠端Server機器上的物件。.NET Framework則…

通过python实现linux切换用户_Python操作远程服务器切换到root用户

在自动化运维过程中&#xff0c;需要远程服务器切换到root用户下执行命令&#xff0c;尝试了一些方法&#xff0c;得到如下好用的方法&#xff0c;供大家使用&#xff1a; import time import paramiko def verification_ssh(host,username,password,port,root_pwd,cmd): spara…