OAuth2客户端的配置参数非常多,虽然Id Server通过控制台可视化解决了创建OAuth2客户端的问题。但是如何进一步降低OAuth2的使用难度,把创建的OAuth2客户端转化为配置成为了刚需,从技术角度上感觉也并不是很难实现。

我们先来看看效果,点击配置生成按钮即可直接生成Spring Security的客户端yaml配置:

这个效果是如何实现的呢?

highlightjs

主要依托于highlightjs这个代码高亮库,平常我们在各大技术社区看到的五颜六色的代码块很多就依赖的这个JS库,连我自己的技术博客felord.cn都用了这个类库来做代码片段美化。它使用起来很简单:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet"
href="https://felord.cn/css/gruvbox-dark.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>
<pre >
<code class="yaml">
spring:
#
application:
name: id-server
</code>
</pre>
</body>
</html>

引入一个风格样式和highlight.js库,再加一个初始化脚本就完成了。然后在<pre><code>中编写带缩进的代码就可以了,注意code标签要加上对应语言或者脚本的class类,出来就是这样的效果:

实现

到这里思路就很明确了,把参数项的值动态化就可以了,我期望达到这样的效果:

<pre >
<code class="yaml">
spring:
#
application:
name: ${appName}
</code>
</pre>

但事实上我大意了,我用了thymeleaf模板,我没有找到thymeleaf可以固化配置项到页面的办法,所以这个带缩进的格式得后端生成,然后按照thymeleaf的要求渲染,于是我写了一个非常复杂的方法:

    @GetMapping("/system/client/yaml/{id}")
public String yaml(Model model, @PathVariable String id) {
OAuth2Client oauth2Client = clientRepository.findClientById(id); String clientName = oauth2Client.getClientName();
String clientId = oauth2Client.getClientId(); Set<RedirectUri> redirectUris = oauth2Client.getRedirectUris();
String uris = redirectUris.stream()
.map(RedirectUri::getRedirectUri)
.collect(Collectors.joining(","));
Set<OAuth2GrantType> authorizationGrantTypes = oauth2Client.getAuthorizationGrantTypes();
String types = authorizationGrantTypes.stream()
.map(OAuth2GrantType::getGrantTypeName)
.collect(Collectors.joining(","));
String method = oauth2Client.getClientAuthenticationMethods().stream()
.map(ClientAuthMethod::getClientAuthenticationMethod)
.collect(Collectors.joining(","));
String scopes = Stream.concat(
oauth2Client.getScopes().stream()
.map(OAuth2Scope::getScope), Stream.of(OidcScopes.OPENID))
.collect(Collectors.joining(",")); LinkedHashMap<String, Object> client = new LinkedHashMap<>();
LinkedHashMap<String, Object> clientRegistration = new LinkedHashMap<>();
clientRegistration.put("client-id", clientId);
clientRegistration.put("client-secret", "请填写你的OAuth2客户端密码");
clientRegistration.put("redirect-uri", "请从" + uris + "指定一个");
clientRegistration.put("authorization-grant-type", "请从 " + types + " 指定一个");
clientRegistration.put("client-authentication-method", method);
clientRegistration.put("scope", scopes);
client.put("registration",
Collections.singletonMap(clientName, clientRegistration));
client.put("provider", Collections.singletonMap(clientName,
Collections.singletonMap("issuer-uri", "http://localhost:9000"))); Map<String, Object> spring =
Collections.singletonMap("spring",
Collections.singletonMap("security",
Collections.singletonMap("oauth2",
Collections.singletonMap("client", client)))); DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions);
String dump = yaml.dump(spring);
model.addAttribute("yaml", dump);
return "/system/client/yaml";
}

效果自然是有的,但是非常差强人意。

无法生成注释,而且换行不受控制,尤其套了9个Map让我抓狂。

优化

是不是我把问题想得太复杂了呢?于是最终我把yaml的格式模板这样做了:

        String yml = "spring:\n" +
" security:\n" +
" oauth2:\n" +
" client:\n" +
" registration:\n" +
" # 这里为客户端名称可自行更改\n" +
" " + clientName + ":\n" +
" client-id: " + clientId + "\n" +
" # 密码为注册客户端时的密码\n" +
" client-secret: 请填写您记忆的OAuth2客户端密码\n" +
" # 只能选择一个\n" +
" redirect-uri: 请从" + uris + "指定一个\n" +
" # 只能选择一个\n" +
" authorization-grant-type: " + types + "三选一\n" +
" client-authentication-method: " + method + "\n" +
" scope: " + scopes + "\n" +
" provider:\n" +
" " + clientName + ":\n" +
" # 要保证授权服务器地址可以被客户端访问\n" +
" issuer-uri: http://localhost:9000"; model.addAttribute("yaml", yml);

当然这是为了兼容Java8,如果换了Java17直接就用字符串模板了,甚至这里我还能写注释,最终的效果是这样的:

效果比上一个方案好了很多,当然或许你还有更好的方案,让我们集思广益。

关于Id Server

仓库地址:https://github.com/NotFound403/id-server 欢迎star。

Id Server是一个基于Spring Authorization Server的开源的授权服务器,大大降低OAuth2授权服务器的学习使用难度,提供UI控制台,动态权限控制,方便OAuth2客户端管理,可以一键生成Spring Security配置,开箱即用,少量配置修改就可部署,代码开源,方便二次开发,支持OAuth2四种客户端认证方式和三种授权模式。欢迎学习使用并参与代码贡献。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

OAuth2授权服务器Id Server一键生成配置原理的更多相关文章

  1. 隔离这几天开发了一个带控制台的OAuth2授权服务器分享给大家

    停更这些天,业余时间和粉丝群的几个大佬合作写了一个基于Spring Authorization Server的OAuth2授权服务器的管理控制台项目Id Server,我觉得这个项目能够大大降低OAu ...

  2. JetBrains 授权服务器(License Server):

    JetBrains 授权服务器(License Server): https://www.imsxm.com/jetbrains-license-server.html

  3. JetBrains 授权服务器(License Server URLS)

    分享几个已经部署好的在线验证服务器:http://idea.iteblog.com/key.php http://idea.imsxm.com/ http://103.207.69.64:1017 h ...

  4. Spring Cloud微服务安全实战_4-5_搭建OAuth2资源服务器

    上一篇搭建了一个OAuth2认证服务器,可以生成token,这篇来改造下之前的订单微服务,使其能够认这个token令牌. 本篇针对订单服务要做三件事: 1,要让他知道自己是资源服务器,他知道这件事后, ...

  5. 入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 创建简单的OAuth2.0服务器,客户端和API(三)

    本教程的目的在于创造尽可能简单的identityserver安装作为一个oauth2授权服务器.这应该能够让你了解一些基本功能和配置选项(完整的源代码可以发现在这里).在后面的文档中会介绍更多的高级功 ...

  6. 如何在Windows Server 2008 上添加RD (远程桌面)会话主机配置的远程桌面授权服务器

    在Windows Server系列的现存活跃产品中都默认的会开放两个随机附送的远程控制的授权,而一些特殊条件下我们需要启用多个远程终端连接,在购买了相应的授权之后,我们如何将配置好的服务器添加到远程桌 ...

  7. Windows Server 2019 配置远程桌面授权服务器许可RD

    Windows Server 2019 配置远程桌面授权服务器许可RD Windows Server 201默认的最大远程登录连接为2个,超过这个数目需要使用license server进行授权,但又 ...

  8. 使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  9. [2014-11-11]使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

随机推荐

  1. Flask-Script使用教程

    Flask使用第三方脚本 一个干净的项目准备: 一个干净的Flask项目连接地址: https://pan.baidu.com/s/123TyVXOFvh5P7V8MbyMfDg 话不多说,上菜: 1 ...

  2. Creating a File View

    创建文件视图 为了映射一个文件的数据到进程的虚拟内存,你必须创建一个文件的视图.MapViewofFile和MapViewofFileEX使用CreateFileMapping返回的句柄,在虚拟地址空 ...

  3. 什么是RESTFUL?REST的请求方法有哪些,有什么区别?

    这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [什么是REST ...

  4. java中Number Type Casting(数字类型强转)的用法

    4.5 Number Type Casting(数字类型强转)隐式 casting(from small to big) byte a = 111; int b = a;显式 casting(from ...

  5. (ICONIP2021)On the Unreasonable Effectiveness of Centroids in Image

    目录 摘要 1.引言 2.提出的方法 2.1 CentroidTripletloss 2.2 聚合表示 3.实验 3.1 数据集 3.2 应用细节 3.3 Fashion检索结果 3.4 行人再识别结 ...

  6. python---用顺序表实现栈

    class Stack(object): """栈, 存放数据的一种容器, 后进先出""" def __init__(self): self ...

  7. Struct2中三种获取表单数据的方式

    1.使用ActionContext类 //1获取ActionContext对象 ActionContext context = ActionContext.getContext(); //2.调用方法 ...

  8. Spring集成web环境(使用封装好的工具)

    接上文spring集成web环境(手动实现) ##########代码接上文############# spring提供了一个监听器ContextLoaderListener对上述功能的封装,该监听器 ...

  9. 20220406Java

    记个笔记 字符串操作类中s1.compareTo(s)规则: Compares two strings lexicographically. The comparison is based on th ...

  10. 索引优化、Sql查询语句优化

    工作中我们经常会遇到系统查询慢的情况,一般我们会采取好多方法进行优化,如建立索引,优化查询Sql,分表,规范数据表结构设计,调整数据库参数(内存分配.缓存等),增加硬件配置,优化网络环境等.下面介绍两 ...