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="https://www.cnblogs.com//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>
<pre >
<code >
spring:
#
application:
name: id-server
</code>
</pre>
</body>
</html>
引入一個風格樣式和highlight.js庫,再加一個初始化腳本就完成了,然后在<pre><code>中撰寫帶縮進的代碼就可以了,注意code標簽要加上對應語言或者腳本的class類,出來就是這樣的效果:

實作
到這里思路就很明確了,把引數項的值動態化就可以了,我期望達到這樣的效果:
<pre >
<code >
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
|
博主:碼農小胖哥 出處:felord.cn 本文著作權歸原作者所有,不可商用,轉載需要宣告出處,否則保留追究法律責任的權利,如果文中有什么錯誤,歡迎指出,以免更多的人被誤導, |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/473429.html
標籤:其他
