Skip to content

Commit cdff38b

Browse files
committed
1
1 parent 686d7dc commit cdff38b

12 files changed

Lines changed: 332 additions & 8 deletions

File tree

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM alpine:3.21
1+
FROM alpine:3.22
22
ENV LANG=zh_CN.UTF-8 \
33
TZ=Asia/Shanghai \
44
PS1="\u@\h:\w \$ "
@@ -13,6 +13,7 @@ RUN apk add --update --no-cache \
1313
nginx-mod-http-headers-more \
1414
nginx-mod-http-js \
1515
nginx-mod-http-keyval \
16+
nginx-mod-http-lua \
1617
nginx-mod-http-brotli \
1718
nginx-mod-rtmp \
1819
nginx-mod-mail \

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ Path : JDK安装目录\bin
111111

112112
```
113113
Linux: mkdir /home/nginxWebUI/
114-
wget -O /home/nginxWebUI/nginxWebUI.jar https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.2/nginxWebUI-4.3.2.jar
114+
wget -O /home/nginxWebUI/nginxWebUI.jar https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.3/nginxWebUI-4.3.3.jar
115115
116-
Windows: 直接使用浏览器下载 https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.2/nginxWebUI-4.3.2.jar 到 D:/home/nginxWebUI/nginxWebUI.jar
116+
Windows: 直接使用浏览器下载 https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.3/nginxWebUI-4.3.3.jar 到 D:/home/nginxWebUI/nginxWebUI.jar
117117
```
118118

119119
有新版本只需要修改路径中的版本即可
@@ -282,7 +282,7 @@ Restart=always
282282
WantedBy=multi-user.target
283283
```
284284

285-
之后执行
285+
2. 之后执行
286286

287287
```
288288
systemctl daemon-reload

README_EN.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ reboot
107107

108108
```
109109
Linux: mkdir /home/nginxWebUI/
110-
wget -O /home/nginxWebUI/nginxWebUI.jar https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.2/nginxWebUI-4.3.2.jar
110+
wget -O /home/nginxWebUI/nginxWebUI.jar https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.3/nginxWebUI-4.3.3.jar
111111
112-
Windows: Download directly from your browser https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.2/nginxWebUI-4.3.2.jar into D:/home/nginxWebUI/
112+
Windows: Download directly from your browser https://gitee.com/cym1102/nginxWebUI/releases/download/4.3.3/nginxWebUI-4.3.3.jar into D:/home/nginxWebUI/
113113
```
114114

115115
With a new version, you just need to change the version in the path
@@ -278,7 +278,7 @@ Restart=always
278278
WantedBy=multi-user.target
279279
```
280280

281-
Then execute
281+
2. Then execute
282282

283283
```
284284
systemctl daemon-reload

pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<modelVersion>4.0.0</modelVersion>
1212
<groupId>com.cym</groupId>
1313
<artifactId>nginxWebUI</artifactId>
14-
<version>4.3.2</version>
14+
<version>4.3.3</version>
1515

1616
<properties>
1717
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -125,6 +125,12 @@
125125
<artifactId>expiringmap</artifactId>
126126
<version>0.5.11</version>
127127
</dependency>
128+
129+
<dependency>
130+
<groupId>com.jayway.jsonpath</groupId>
131+
<artifactId>json-path</artifactId>
132+
<version>2.6.0</version>
133+
</dependency>
128134
</dependencies>
129135

130136
<build>

src/main/java/com/cym/config/AppFilter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ private boolean adminInterceptor(Context ctx) {
171171
if (ctx.path().toLowerCase().contains("adminPage/login".toLowerCase())) {
172172
return true;
173173
}
174+
if (ctx.path().toLowerCase().contains("adminPage/sso/code".toLowerCase())) {
175+
return true;
176+
}
174177

175178
String creditKey = ctx.param("creditKey");
176179
boolean isCredit = creditService.check(creditKey);
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.cym.controller.adminPage;
2+
3+
import cn.hutool.core.lang.UUID;
4+
import cn.hutool.core.util.StrUtil;
5+
import cn.hutool.http.HttpUtil;
6+
import cn.hutool.json.JSONObject;
7+
import cn.hutool.json.JSONUtil;
8+
import com.cym.ext.AdminExt;
9+
import com.cym.ext.Tree;
10+
import com.cym.model.Admin;
11+
import com.cym.model.Group;
12+
import com.cym.service.AdminService;
13+
import com.cym.service.GroupService;
14+
import com.cym.service.SettingService;
15+
import com.cym.sqlhelper.bean.Page;
16+
import com.cym.sqlhelper.utils.ConditionAndWrapper;
17+
import com.cym.utils.*;
18+
import com.google.zxing.BarcodeFormat;
19+
import com.google.zxing.EncodeHintType;
20+
import com.google.zxing.MultiFormatWriter;
21+
import com.google.zxing.WriterException;
22+
import com.google.zxing.client.j2se.MatrixToImageWriter;
23+
import com.google.zxing.common.BitMatrix;
24+
import com.jayway.jsonpath.JsonPath;
25+
import org.noear.solon.annotation.Controller;
26+
import org.noear.solon.annotation.Inject;
27+
import org.noear.solon.annotation.Mapping;
28+
import org.noear.solon.core.handle.Context;
29+
import org.noear.solon.core.handle.ModelAndView;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
32+
33+
import java.io.IOException;
34+
import java.util.*;
35+
36+
@Controller
37+
@Mapping("/adminPage/sso")
38+
public class SSOController extends BaseController {
39+
Logger logger = LoggerFactory.getLogger(this.getClass());
40+
@Inject
41+
AdminService adminService;
42+
@Inject
43+
SettingService settingService;
44+
@Inject
45+
SendMailUtils sendCloudUtils;
46+
@Inject
47+
AuthUtils authUtils;
48+
@Inject
49+
GroupService groupService;
50+
@Inject
51+
RemoteController remoteController;
52+
53+
@Mapping("")
54+
public ModelAndView index(ModelAndView modelAndView) {
55+
56+
modelAndView.put("codeUrl", settingService.get("sso_codeUrl"));
57+
modelAndView.put("tokenUrl", settingService.get("sso_tokenUrl"));
58+
modelAndView.put("userinfoUrl", settingService.get("sso_userinfoUrl"));
59+
modelAndView.put("jsonpath", settingService.get("sso_jsonpath"));
60+
modelAndView.put("clientID", settingService.get("sso_clientID"));
61+
modelAndView.put("clientSecret", settingService.get("sso_clientSecret"));
62+
modelAndView.view("/adminPage/sso/index.html");
63+
return modelAndView;
64+
}
65+
66+
@Mapping("save")
67+
public JsonResult save(String codeUrl, String tokenUrl, String userinfoUrl, String jsonpath, String clientID, String clientSecret, String callbackUrl) {
68+
69+
settingService.set("sso_codeUrl", codeUrl);
70+
settingService.set("sso_tokenUrl", tokenUrl);
71+
settingService.set("sso_userinfoUrl", userinfoUrl);
72+
settingService.set("sso_jsonpath", jsonpath);
73+
settingService.set("sso_clientID", clientID);
74+
settingService.set("sso_clientSecret", clientSecret);
75+
settingService.set("sso_callbackUrl", callbackUrl);
76+
77+
return renderSuccess();
78+
}
79+
80+
@Mapping("redirect")
81+
public void redirect(Context ctx) {
82+
83+
String codeUrl = settingService.get("sso_codeUrl");
84+
String clientID = settingService.get("sso_clientID");
85+
String callbackUrl = settingService.get("sso_callbackUrl");
86+
87+
String url = codeUrl + "?client_id=" + clientID + "&response_type=code&redirect_uri=" + callbackUrl + "&oauth_timestamp=" + System.currentTimeMillis() + "&state=";
88+
89+
ctx.redirect(url);
90+
}
91+
92+
@Mapping("code")
93+
public void code(String code, Context ctx) {
94+
95+
String tokenUrl = settingService.get("sso_tokenUrl");
96+
String userinfoUrl = settingService.get("sso_userinfoUrl");
97+
String jsonpath = settingService.get("sso_jsonpath");
98+
String clientID = settingService.get("sso_clientID");
99+
String clientSecret = settingService.get("sso_clientSecret");
100+
String callbackUrl = settingService.get("sso_callbackUrl");
101+
102+
String getTokenUrl = tokenUrl + "?grant_type=authorization_code&oauth_timestamp=" + System.currentTimeMillis() + "&client_id=" + clientID + "&client_secret=" + clientSecret + "&code=" + code
103+
+ "&redirect_uri=" + callbackUrl;
104+
105+
String post = HttpUtil.post(getTokenUrl, "");
106+
107+
JSONObject entries = JSONUtil.parseObj(post);
108+
String accessToken = entries.getStr("access_token");
109+
110+
String userInfoUrl = userinfoUrl + "?access_token=" + accessToken;
111+
112+
String userinfoStr = HttpUtil.get(userInfoUrl);
113+
114+
String read = JsonPath.read(userinfoStr, jsonpath);
115+
116+
Admin admin = sqlHelper.findOneByQuery(new ConditionAndWrapper().eq(Admin::getName, read), Admin.class);
117+
118+
admin.setAutoKey(UUID.randomUUID().toString()); // 生成自动登录code
119+
sqlHelper.updateById(admin);
120+
121+
Context.current().sessionSet("localType", "local");
122+
Context.current().sessionSet("isLogin", true);
123+
Context.current().sessionSet("admin", admin);
124+
Context.current().sessionRemove("imgCode"); // 立刻销毁验证码
125+
126+
ctx.redirect("/adminPage/monitor");
127+
}
128+
}

src/main/resources/WEB-INF/view/adminPage/login/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<div class="layui-form-item" style="text-align: center;">
4747
<input type="hidden" name="authCode" id="authCode">
4848
<button type="button" class="layui-btn layui-btn-normal" onclick="getAuth()">${loginStr.login}</button>
49+
<a type="button" class="layui-btn layui-btn-normal" href="/adminPage/sso/redirect" >${menuStr.sso}</a>
4950
</div>
5051
</form>
5152
</div>

src/main/resources/WEB-INF/view/adminPage/menu.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@
7777
<dd>
7878
<a href="${ctx}/adminPage/admin">${menuStr.admin}</a>
7979
</dd>
80+
<dd>
81+
<a href="${ctx}/adminPage/sso">${menuStr.sso}</a>
82+
</dd>
8083
</#if>
8184
<dd>
8285
<a href="${ctx}/doc/api.html" target="_blank">${menuStr.doc}</a>
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<!DOCTYPE HTML>
2+
<html>
3+
<head>
4+
<#include "/adminPage/common.html"/>
5+
<link rel="stylesheet" type="text/css" href="${ctx}/lib/jsdifflib/diffview.css" />
6+
<style type="text/css">
7+
.layui-form-label {
8+
width: 140px;
9+
}
10+
11+
.layui-input-block {
12+
margin-left: 170px;
13+
}
14+
15+
.name {
16+
padding: 10px;
17+
padding-left: 0px;
18+
font-size: 16px;
19+
}
20+
21+
.title {
22+
margin-top: 5px;
23+
margin-bottom: 5px;
24+
height: 30px;
25+
line-height: 30px;
26+
cursor: pointer;
27+
}
28+
29+
table.diff {
30+
width: 100%;
31+
}
32+
33+
.long {
34+
width: 150px !important;
35+
}
36+
37+
.layui-form-radio {
38+
width: 700px;
39+
}
40+
41+
input[type='radio'] {
42+
width: 1000px;
43+
}
44+
</style>
45+
</head>
46+
<body class="layui-layout-body">
47+
<div class="layui-layout layui-layout-admin">
48+
49+
<#include "/adminPage/header.html"/>
50+
<#include "/adminPage/menu.html"/>
51+
52+
<div class="layui-body">
53+
<!-- 内容主体区域 -->
54+
<fieldset class="layui-elem-field layui-field-title">
55+
<legend>SSO-OAuth2.0配置</legend>
56+
</fieldset>
57+
<form id="addForm" style="margin-top: 48px">
58+
59+
<div class="layui-form-item">
60+
<label class="layui-form-label">${ssoStr.codeAddr}</label>
61+
<div class="layui-input-block">
62+
<input type="text" name="codeUrl" id="codeUrl" class="layui-input" value="${codeUrl}">
63+
</div>
64+
</div>
65+
66+
<div class="layui-form-item">
67+
<label class="layui-form-label">${ssoStr.tokenAddr}</label>
68+
<div class="layui-input-block">
69+
<input type="text" name="tokenUrl" id="tokenUrl" class="layui-input" value="${tokenUrl}">
70+
</div>
71+
</div>
72+
73+
<div class="layui-form-item">
74+
<label class="layui-form-label">${ssoStr.userinfoAddr}</label>
75+
<div class="layui-input-block">
76+
<input type="text" name="userinfoUrl" id="userinfoUrl" class="layui-input" value="${userinfoUrl}">
77+
</div>
78+
</div>
79+
80+
81+
<div class="layui-form-item">
82+
<label class="layui-form-label">${ssoStr.jsonpath}</label>
83+
<div class="layui-input-block">
84+
<input type="text" name="jsonpath" id="jsonpath" class="layui-input" value="${jsonpath}" placeholder="${ssoStr.placeholder}">
85+
</div>
86+
</div>
87+
88+
<div class="layui-form-item">
89+
<label class="layui-form-label">clientID</label>
90+
<div class="layui-input-block">
91+
<input type="text" name="clientID" id="clientID" class="layui-input" value="${clientID}">
92+
</div>
93+
</div>
94+
95+
<div class="layui-form-item">
96+
<label class="layui-form-label">clientSecret</label>
97+
<div class="layui-input-block">
98+
<input type="text" name="clientSecret" id="clientSecret" class="layui-input" value="${clientSecret}">
99+
</div>
100+
</div>
101+
102+
<div class="layui-form-item">
103+
<label class="layui-form-label">${ssoStr.callbackAddr}</label>
104+
<div class="layui-input-block">
105+
<input id="callbackUrl" name="callbackUrl" class="layui-input">
106+
</div>
107+
</div>
108+
109+
110+
<div class="layui-form-item center">
111+
<button type="button" class="layui-btn layui-btn-normal" onclick="save()">${commonStr.submit}</button>
112+
</div>
113+
</form>
114+
115+
</div>
116+
</div>
117+
118+
119+
120+
<#include '/adminPage/script.html'/>
121+
<#include '/adminPage/select_root.html'/>
122+
<script src="${ctx}/lib/auto-line-number/auto-line-number.js" type="text/javascript"></script>
123+
<script src="${ctx}/lib/jsdifflib/difflib.js" type="text/javascript"></script>
124+
<script src="${ctx}/lib/jsdifflib/diffview.js" type="text/javascript"></script>
125+
<script src="${ctx}/lib/base64/base64.js" type="text/javascript"></script>
126+
<script type="application/javascript">
127+
128+
129+
const href = location.href.split('/');
130+
const host = href[0]+"//"+href[2];
131+
document.getElementById("callbackUrl").value=host+"/adminPage/sso/code";//host+"/adminPage/sso/code?code=xxxxxxx";
132+
133+
async function save(){
134+
const form = document.getElementById('addForm');
135+
const formData = new FormData(form);
136+
const response = await fetch('/adminPage/sso/save', {
137+
method: 'POST',
138+
body: formData
139+
});
140+
const data = await response.json();
141+
if (data.success) {
142+
layer.msg(ssoStr.success)
143+
}else {
144+
layer.msg(data.msg)
145+
}
146+
}
147+
148+
</script>
149+
</body>
150+
151+
152+
</html>

0 commit comments

Comments
 (0)