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/NotFound40... 欢送star。

Id Server是一个基于Spring Authorization Server的开源的受权服务器,大大降低OAuth2受权服务器的学习应用难度,提供UI控制台,动静权限管制,不便OAuth2客户端治理,能够一键生成Spring Security配置,开箱即用,大量配置批改就可部署,代码开源,不便二次开发,反对OAuth2四种客户端认证形式和三种受权模式。欢送学习应用并参加代码奉献。

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

集体博客:https://felord.cn