Compare commits

...

4 Commits

Author SHA1 Message Date
OnEvent
fcb07297e6 Merge af8be721c5 into f9774698e9 2024-08-13 15:26:24 +08:00
OnEvent
af8be721c5 feat: Standardize terminology, add well-known configuration
- Change the AppId and AppSecret on the Server End to the standard usage: ClientId, ClientSecret.
- add Well-Known configuration to store in database, no actual use in server end but store and display in web ui only
2024-08-13 15:26:05 +08:00
OnEvent
e66b73faf5 feat: Support quick configuration of OIDC through Well-Known Discovery Endpoint 2024-08-13 14:35:06 +08:00
OnEvent
f8144fe534 fix: Change the AppId and AppSecret on the Web UI to the standard usage: ClientId, ClientSecret. 2024-08-13 13:57:46 +08:00
8 changed files with 84 additions and 50 deletions

View File

@@ -71,8 +71,9 @@ var GitHubClientSecret = ""
var LarkClientId = ""
var LarkClientSecret = ""
var OidcAppId = ""
var OidcAppSecret = ""
var OidcClientId = ""
var OidcClientSecret = ""
var OidcWellKnown = ""
var OidcAuthorizationEndpoint = ""
var OidcTokenEndpoint = ""
var OidcUserinfoEndpoint = ""

View File

@@ -38,8 +38,8 @@ func getOidcUserInfoByCode(code string) (*OidcUser, error) {
return nil, errors.New("无效的参数")
}
values := map[string]string{
"client_id": config.OidcAppId,
"client_secret": config.OidcAppSecret,
"client_id": config.OidcClientId,
"client_secret": config.OidcClientSecret,
"code": code,
"grant_type": "authorization_code",
"redirect_uri": fmt.Sprintf("%s/oauth/oidc", config.ServerAddress),

View File

@@ -37,7 +37,8 @@ func GetStatus(c *gin.Context) {
"quota_per_unit": config.QuotaPerUnit,
"display_in_currency": config.DisplayInCurrencyEnabled,
"oidc": config.OidcEnabled,
"oidc_app_id": config.OidcAppId,
"oidc_client_id": config.OidcClientId,
"oidc_well_known": config.OidcWellKnown,
"oidc_authorization_endpoint": config.OidcAuthorizationEndpoint,
"oidc_token_endpoint": config.OidcTokenEndpoint,
"oidc_userinfo_endpoint": config.OidcUserinfoEndpoint,

View File

@@ -179,10 +179,12 @@ func updateOptionMap(key string, value string) (err error) {
config.LarkClientId = value
case "LarkClientSecret":
config.LarkClientSecret = value
case "OidcAppId":
config.OidcAppId = value
case "OidcAppSecret":
config.OidcAppSecret = value
case "OidcClientId":
config.OidcClientId = value
case "OidcClientSecret":
config.OidcClientSecret = value
case "OidcWellKnown":
config.OidcWellKnown = value
case "OidcAuthorizationEndpoint":
config.OidcAuthorizationEndpoint = value
case "OidcTokenEndpoint":

View File

@@ -24,7 +24,7 @@ const config = {
wechat_login: false,
wechat_qrcode: '',
oidc: false,
oidc_app_id: '',
oidc_client_id: '',
oidc_authorization_endpoint: '',
oidc_token_endpoint: '',
oidc_userinfo_endpoint: '',

View File

@@ -152,7 +152,7 @@ const LoginForm = ({ ...others }) => {
<Button
disableElevation
fullWidth
onClick={() => onOidcClicked(siteInfo.oidc_authorization_endpoint,siteInfo.oidc_app_id)}
onClick={() => onOidcClicked(siteInfo.oidc_authorization_endpoint,siteInfo.oidc_client_id)}
size="large"
variant="outlined"
sx={{

View File

@@ -231,7 +231,7 @@ export default function Profile() {
)}
{status.oidc && !inputs.oidc_id && (
<Grid xs={12} md={4}>
<Button variant="contained" onClick={() => onOidcClicked(status.oidc_authorization_endpoint,status.oidc_app_id,true)}>
<Button variant="contained" onClick={() => onOidcClicked(status.oidc_authorization_endpoint,status.oidc_client_id,true)}>
绑定 OIDC 账号
</Button>
</Grid>

View File

@@ -34,8 +34,9 @@ const SystemSetting = () => {
LarkClientId: '',
LarkClientSecret: '',
OidcEnabled: '',
OidcAppId: '',
OidcAppSecret: '',
OidcWellKnown: '',
OidcClientId: '',
OidcClientSecret: '',
OidcAuthorizationEndpoint: '',
OidcTokenEndpoint: '',
OidcUserinfoEndpoint: '',
@@ -150,8 +151,9 @@ const SystemSetting = () => {
name === 'MessagePusherToken' ||
name === 'LarkClientId' ||
name === 'LarkClientSecret' ||
name === 'OidcAppId' ||
name === 'OidcAppSecret' ||
name === 'OidcClientId' ||
name === 'OidcClientSecret' ||
name === 'OidcWellKnown' ||
name === 'OidcAuthorizationEndpoint' ||
name === 'OidcTokenEndpoint' ||
name === 'OidcUserinfoEndpoint'
@@ -239,19 +241,30 @@ const SystemSetting = () => {
};
const submitOidc = async () => {
const OidcConfig = {
OidcAppId: inputs.OidcAppId,
OidcAppSecret: inputs.OidcAppSecret,
OidcAuthorizationEndpoint: inputs.OidcAuthorizationEndpoint,
OidcTokenEndpoint: inputs.OidcTokenEndpoint,
OidcUserinfoEndpoint: inputs.OidcUserinfoEndpoint
};
console.log(OidcConfig);
if (originInputs['OidcAppId'] !== inputs.OidcAppId) {
await updateOption('OidcAppId', inputs.OidcAppId);
if (inputs.OidcWellKnown !== '') {
if (!inputs.OidcWellKnown.startsWith('http://') && !inputs.OidcWellKnown.startsWith('https://')) {
showError('Well-Known URL 必须以 http:// 或 https:// 开头');
return;
}
try {
const res = await API.get(inputs.OidcWellKnown);
inputs.OidcAuthorizationEndpoint = res.data['authorization_endpoint'];
inputs.OidcTokenEndpoint = res.data['token_endpoint'];
inputs.OidcUserinfoEndpoint = res.data['userinfo_endpoint'];
showSuccess('获取 OIDC 配置成功!');
} catch (err) {
showError("获取 OIDC 配置失败,请检查网络状况和 Well-Known URL 是否正确");
}
}
if (originInputs['OidcAppSecret'] !== inputs.OidcAppSecret && inputs.OidcAppSecret !== '') {
await updateOption('OidcAppSecret', inputs.OidcAppSecret);
if (originInputs['OidcWellKnown'] !== inputs.OidcWellKnown) {
await updateOption('OidcWellKnown', inputs.OidcWellKnown);
}
if (originInputs['OidcClientId'] !== inputs.OidcClientId) {
await updateOption('OidcClientId', inputs.OidcClientId);
}
if (originInputs['OidcClientSecret'] !== inputs.OidcClientSecret && inputs.OidcClientSecret !== '') {
await updateOption('OidcClientSecret', inputs.OidcClientSecret);
}
if (originInputs['OidcAuthorizationEndpoint'] !== inputs.OidcAuthorizationEndpoint) {
await updateOption('OidcAuthorizationEndpoint', inputs.OidcAuthorizationEndpoint);
@@ -332,7 +345,7 @@ const SystemSetting = () => {
</Grid>
<Grid xs={12} md={3}>
<FormControlLabel
label="允许通过 Oidc 登录 & 注册"
label="允许通过 OIDC 登录 & 注册"
control={<Checkbox checked={inputs.OidcEnabled === 'true'} onChange={handleInputChange} name="OidcEnabled" />}
/>
</Grid>
@@ -675,31 +688,34 @@ const SystemSetting = () => {
<Alert severity="info" sx={ { wordWrap: 'break-word' } }>
主页链接填 <code>{ inputs.ServerAddress }</code>
重定向 URL <code>{ `${ inputs.ServerAddress }/oauth/oidc` }</code>
</Alert> <br />
<Alert severity="info" sx={ { wordWrap: 'break-word' } }>
若你的 OIDC Provider 支持 Discovery Endpoint你可以仅填写 OIDC Well-Known URL系统会自动获取 OIDC 配置
</Alert>
</Grid>
<Grid xs={ 12 } md={ 6 }>
<FormControl fullWidth>
<InputLabel htmlFor="OidcAppId">App ID</InputLabel>
<InputLabel htmlFor="OidcClientId">Client ID</InputLabel>
<OutlinedInput
id="OidcAppId"
name="OidcAppId"
value={ inputs.OidcAppId || '' }
id="OidcClientId"
name="OidcClientId"
value={ inputs.OidcClientId || '' }
onChange={ handleInputChange }
label="App ID"
placeholder="输入 OAuth 2.0 的 App ID"
label="Client ID"
placeholder="输入 OIDC 的 Client ID"
disabled={ loading }
/>
</FormControl>
</Grid>
<Grid xs={ 12 } md={ 6 }>
<FormControl fullWidth>
<InputLabel htmlFor="OidcAppSecret">App Secret</InputLabel>
<InputLabel htmlFor="OidcClientSecret">Client Secret</InputLabel>
<OutlinedInput
id="OidcAppSecret"
name="OidcAppSecret"
value={ inputs.OidcAppSecret || '' }
id="OidcClientSecret"
name="OidcClientSecret"
value={ inputs.OidcClientSecret || '' }
onChange={ handleInputChange }
label="App Secret"
label="Client Secret"
placeholder="敏感信息不会发送到前端显示"
disabled={ loading }
/>
@@ -707,49 +723,63 @@ const SystemSetting = () => {
</Grid>
<Grid xs={ 12 } md={ 6 }>
<FormControl fullWidth>
<InputLabel htmlFor="OidcAuthorizationEndpoint">授权地址</InputLabel>
<InputLabel htmlFor="OidcWellKnown">Well-Known URL</InputLabel>
<OutlinedInput
id="OidcWellKnown"
name="OidcWellKnown"
value={ inputs.OidcWellKnown || '' }
onChange={ handleInputChange }
label="Well-Known URL"
placeholder="请输入 OIDC 的 Well-Known URL"
disabled={ loading }
/>
</FormControl>
</Grid>
<Grid xs={ 12 } md={ 6 }>
<FormControl fullWidth>
<InputLabel htmlFor="OidcAuthorizationEndpoint">Authorization Endpoint</InputLabel>
<OutlinedInput
id="OidcAuthorizationEndpoint"
name="OidcAuthorizationEndpoint"
value={ inputs.OidcAuthorizationEndpoint || '' }
onChange={ handleInputChange }
label="授权地址"
placeholder="输入 OAuth 2.0 的 授权地址"
label="Authorization Endpoint"
placeholder="输入 OIDC 的 Authorization Endpoint"
disabled={ loading }
/>
</FormControl>
</Grid>
<Grid xs={ 12 } md={ 6 }>
<FormControl fullWidth>
<InputLabel htmlFor="OidcTokenEndpoint">认证地址</InputLabel>
<InputLabel htmlFor="OidcTokenEndpoint">Token Endpoint</InputLabel>
<OutlinedInput
id="OidcTokenEndpoint"
name="OidcTokenEndpoint"
value={ inputs.OidcTokenEndpoint || '' }
onChange={ handleInputChange }
label="认证地址"
placeholder="输入 OAuth 2.0 的 认证地址"
label="Token Endpoint"
placeholder="输入 OIDC 的 Token Endpoint"
disabled={ loading }
/>
</FormControl>
</Grid>
<Grid xs={ 12 } md={ 6 }>
<FormControl fullWidth>
<InputLabel htmlFor="OidcUserinfoEndpoint">用户地址</InputLabel>
<InputLabel htmlFor="OidcUserinfoEndpoint">Userinfo Endpoint</InputLabel>
<OutlinedInput
id="OidcUserinfoEndpoint"
name="OidcUserinfoEndpoint"
value={ inputs.OidcUserinfoEndpoint || '' }
onChange={ handleInputChange }
label="认证地址"
placeholder="输入 OAuth 2.0 的 认证地址"
label="Userinfo Endpoint"
placeholder="输入 OIDC 的 Userinfo Endpoint"
disabled={ loading }
/>
</FormControl>
</Grid>
<Grid xs={ 12 }>
<Button variant="contained" onClick={ submitOidc }>
保存第三方 OAuth 2.0 设置
保存 OIDC 设置
</Button>
</Grid>
</Grid>