前面的部分:

Identity Server 4 从入门到落地(一)—— 从IdentityServer4.Admin开始

Identity Server 4 从入门到落地(二)—— 理解授权码模式

Identity Server 4 从入门到落地(三)—— 创建Web客户端

Identity Server 4 从入门到落地(四)—— 创建Web Api

Identity Server 4 从入门到落地(五)—— 使用Ajax 访问 Web Api

认证服务和管理的github地址: https://github.com/zhenl/IDS4Admin

客户端及web api示例代码的github地址:https://github.com/zhenl/IDS4ClientDemo

前面我们在Web应用的页面上使用Ajax访问Web Api, 这种情况下,认证以及获取Access Token还是在后台进行的,而真正的单页面应用没有后台的参与,web服务器只起到host文件的作用,这部分我们编写简单的单页面应用,试验一下单页面访问受认证保护的Web Api。

我们参考Identity Server 4的官网示例编写这个单页面应用,将其中的认证服务器改为我们本地运行的认证服务http://localhost:4010,Web Api使用前面编写的简单示例,地址为http://localhost:5153。在编写之前,首先下载oidc的客户端,可以从github下载: https://github.com/IdentityModel/oidc-client-js/releases/tag/1.11.5 。我们使用编译完成的最终文件,将下载的文件解压,dist目录就是我们需要的文件。

首先使用Visual Studio 2022创建一个空的Asp.Net Core Web项目,我们使用这个项目作为html和js文件的宿主,除此之外不做其它工作。在项目目录下创建wwwroot目录,用于保存html和js文件,将下载的dist目录拷贝到这个目录中,目录名字改为oidc-client-js-1.11.5。然后在wwwroot下创建index.html、callback.html和app.js三个文件,文件的内容在后面填写。项目的结构如下:



然后修改lanuchSettings.json,项目的运行地址是http://localhost:5210:

{
"profiles": {
"IDS4ClientJS": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5210",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

接下来修改program.cs,使应用支持静态文件:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseDefaultFiles();
app.UseStaticFiles();
app.Run();

这样修改后,项目将Index.html作为缺省页面。

然后就是修改Index.html、callback.html和app.js中的内容。

Index.html中的内容如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button id="login">Login</button>
<button id="api">Call API</button>
<button id="logout">Logout</button> <pre id="results"></pre> <script src="oidc-client-js-1.11.5/oidc-client.js"></script>
<script src="app.js"></script>
</body>
</html>

内容很简单,就是创建三个按钮,分别是登录、登出和调用Api。所实现的功能在app.js中定义:

function log() {
document.getElementById('results').innerText = ''; 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);
}
document.getElementById('results').innerHTML += msg + '\r\n';
});
} document.getElementById("login").addEventListener("click", login, false);
document.getElementById("api").addEventListener("click", api, false);
document.getElementById("logout").addEventListener("click", logout, false); var config = {
authority: "http://localhost:4010",
client_id: "js",
redirect_uri: "http://localhost:5210/callback.html",
response_type: "code",
scope: "openid profile myapi",
post_logout_redirect_uri: "http://localhost:5210/index.html",
};
var mgr = new Oidc.UserManager(config); mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
}
else {
log("User not logged in");
}
}); function login() {
mgr.signinRedirect();
} function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5153/WeatherForecast"; var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
}
xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
xhr.send();
});
} function logout() {
mgr.signoutRedirect();
}

app.js使用oidc js客户端中定义的Oidc.UserManager实现对认证服务器的访问,完成认证和获取access token的工作,其配置在config 中定义,

var config = {
authority: "http://localhost:4010",
client_id: "js",
redirect_uri: "http://localhost:5210/callback.html",
response_type: "code",
scope: "openid profile myapi",
post_logout_redirect_uri: "http://localhost:5210/index.html",
};

最后,定义callback.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script src="oidc-client-js-1.11.5/oidc-client.js"></script>
<script>
new Oidc.UserManager({response_mode:"query"}).signinRedirectCallback().then(function() {
window.location = "index.html";
}).catch(function(e) {
console.error(e);
});
</script>
</body>
</html>

到此,客户端编写完成,我们还需要在认证服务管理中定义这个客户端,注意,在定义时需要选择单页面应用:



参考上面config中的定义设置客户端的其它部分:





最后一项工作是修改Web Api,增加这个网址的CORS设置:

builder.Services.AddCors(option => option.AddPolicy("cors",
policy => policy.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithOrigins(new[] { "https://localhost:7002", "http://localhost:5210" })));

好了,现在可以测试一下这个应用了,在Visual Studio中将解决方案的启动项目设置为多项目启动,同时启动JSClient和Web Api项目:

按F5运行,界面如下:



点击Login,会重定位到认证服务器的登录界面,登录完成后会显示用户的信息:



点击Call Api,会访问Web Api并显示结果:



到此,单页面客户端完成。相关代码可以从github下载: https://github.com/zhenl/IDS4ClientDemo

Identity Server 4 从入门到落地(六)—— 简单的单页面客户端的更多相关文章

  1. Identity Server 4 从入门到落地(八)—— .Net Framework 客户端

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  2. Identity Server 4 从入门到落地(三)—— 创建Web客户端

    书接上回,我们已经搭建好了基于Identity Server 4的认证服务和管理应用(如果还没有搭建,参看本系列前两部分,相关代码可以从github下载:https://github.com/zhen ...

  3. Identity Server 4 从入门到落地(七)—— 控制台客户端

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  4. Identity Server 4 从入门到落地(九)—— 客户端User和Role的解析

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  5. Identity Server 4 从入门到落地(十)—— 编写可配置的客户端和Web Api

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  6. Identity Server 4 从入门到落地(十一)—— Docker部署

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  7. Identity Server 4 从入门到落地(十二)—— 使用Nginx集成认证服务

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  8. Identity Server 4 从入门到落地(五)—— 使用Ajax访问Web Api

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  9. Identity Server 4 从入门到落地(四)—— 创建Web Api

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

随机推荐

  1. Java-基础-LinkedList

    1. 简介 LinkedList 同时实现了List和Deque接口,也就是说它既可以看作是一个顺序容器,又可以看作是双向队列. 既然是双向列表,那么它的每个数据节点都一定有两个指针,分别指向它的前驱 ...

  2. Netty:Netty的介绍以及它的核心组件(三)—— 事件和ChannelHandler

    Netty 使用异步事件驱动(Asynchronous Event-Driven)的应用程序范式,因此数据处理的管道(ChannelPipeLine)是经过处理程序(ChannelHandler)的事 ...

  3. TensorFlow从入门到入坑(1)

    初识TensorFlow 一.术语潜知 深度学习:深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法. 深度学 ...

  4. Verdi Protocol Analyzer Debug 简单使用

    转载:Verdi Protocol Analyzer Debug 简单使用_Holden_Liu的博客-CSDN博客_verdi 技巧 文档与源码: User Guide: UVMDebugUserG ...

  5. 基于live555开发嵌入式linux系统的rtsp直播服务

    最近要搞一个直播服务,车机本身是个前后双路的Dvr,前路1080P 25fps,后路720P 50fps,现在要连接手机app预览实时画面,且支持前后摄像头画面切换. 如果要做直播,这个分辨率和帧率是 ...

  6. Luogu P1023 [NOIp2000提高组]税收与补贴问题 | 数学

    题目链接 思路:列不等式组,然后解出不等式,得出答案的取值范围,最后取一个绝对值最小的答案就行了. #include<iostream> #include<cstdio> #i ...

  7. JAVA笔记4__static关键字/对象数组/foreach/方法的可变参数

    /** * static关键字:修饰属性(实质就是全局变量).方法(无需本类的对象即可调用此方法).类. * 1.static方法只能调用static方法 * 2.static方法只能访问static ...

  8. idea如何在终端使用git并解决终端中文乱码

    idea使用git终端 在idea设置中 找到Settings-Tools-Terminal-Shell path,替换为git安装目录下的bin/bash.exe 解决中文乱码 在git安装目录下找 ...

  9. Part 16 ng include directive in AngularJS

    ng-include directive is used to embed an HTML page into another HTML page. This technique is extreme ...

  10. Django 小实例S1 简易学生选课管理系统 4 实现登录页面

    Django 小实例S1 简易学生选课管理系统 第4节--实现登录页面 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 本文涉及到的新的额外知识点: ...