fix(oidc): bugs of integration with logto (#2032)

* fix(oidc): iss validate bug

* chore: pass iss instend of all values

* fix(oidc): use BroadcastChannel & add alg options

* chore(oidc): improve
This commit is contained in:
YANG QIA 2023-06-12 11:50:56 +08:00 committed by GitHub
parent 47859c0f99
commit f1feb56743
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1938 additions and 1888 deletions

View File

@ -53,9 +53,6 @@ export const OIDCButton = (props: { authenticator: Authenticator }) => {
redirect(); redirect();
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} finally {
windowHandler.close();
setWindowHandler(undefined);
} }
}); });
@ -65,9 +62,10 @@ export const OIDCButton = (props: { authenticator: Authenticator }) => {
useEffect(() => { useEffect(() => {
if (!windowHandler) return; if (!windowHandler) return;
window.addEventListener('message', handleOIDCLogin); const channel = new BroadcastChannel('nocobase-oidc-response');
channel.onmessage = handleOIDCLogin;
return () => { return () => {
window.removeEventListener('message', handleOIDCLogin); channel.close();
}; };
}, [windowHandler, handleOIDCLogin]); }, [windowHandler, handleOIDCLogin]);

View File

@ -39,11 +39,41 @@ const schema = {
tooltip: '{{t("Default: openid profile email")}}', tooltip: '{{t("Default: openid profile email")}}',
}, },
}, },
idTokenSignedResponseAlg: {
title: '{{t("id_token signed response algorithm")}}',
'x-component': 'Select',
'x-decorator': 'FormItem',
enum: [
{ label: 'HS256', value: 'HS256' },
{ label: 'HS384', value: 'HS384' },
{ label: 'HS512', value: 'HS512' },
{ label: 'RS256', value: 'RS256' },
{ label: 'RS384', value: 'RS384' },
{ label: 'RS512', value: 'RS512' },
{ label: 'ES256', value: 'ES256' },
{ label: 'ES384', value: 'ES384' },
{ label: 'ES512', value: 'ES512' },
{ label: 'PS256', value: 'PS256' },
{ label: 'PS384', value: 'PS384' },
{ label: 'PS512', value: 'PS512' },
],
},
http: { http: {
title: '{{t("http")}}', title: '{{t("HTTP")}}',
'x-component': 'Checkbox', 'x-component': 'Checkbox',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
}, },
port: {
title: '{{t("Port")}}',
'x-component': 'InputNumber',
'x-decorator': 'FormItem',
'x-component-props': {
style: {
width: '15%',
'min-width': '100px',
},
},
},
fieldMap: { fieldMap: {
title: '{{t("Field Map")}}', title: '{{t("Field Map")}}',
type: 'array', type: 'array',

View File

@ -5,4 +5,5 @@ export default {
Edit: '编辑', Edit: '编辑',
Copied: '已复制', Copied: '已复制',
'Field Map': '字段映射', 'Field Map': '字段映射',
'id_token signed response algorithm': 'id_token签名算法',
}; };

View File

@ -14,7 +14,9 @@ export const redirect = async (ctx: Context, next) => {
</head> </head>
<body> <body>
<script> <script>
window.opener.postMessage(${JSON.stringify(params)}, '*'); const channel = new BroadcastChannel('nocobase-oidc-response');
channel.postMessage(${JSON.stringify(params)})
window.close();
</script> </script>
</body> </body>
</html> </html>

View File

@ -13,9 +13,10 @@ export class OIDCAuth extends BaseAuth {
getRedirectUri() { getRedirectUri() {
const ctx = this.ctx; const ctx = this.ctx;
const { http } = this.getOptions(); const { http, port } = this.getOptions();
const protocol = http ? 'http' : 'https'; const protocol = http ? 'http' : 'https';
return `${protocol}://${ctx.host}/api/oidc:redirect`; const host = port ? `${ctx.hostname}${port ? `:${port}` : ''}` : ctx.host;
return `${protocol}://${host}/api/oidc:redirect`;
} }
getOptions() { getOptions() {
@ -37,11 +38,12 @@ export class OIDCAuth extends BaseAuth {
} }
async createOIDCClient() { async createOIDCClient() {
const { issuer, clientId, clientSecret } = this.getOptions(); const { issuer, clientId, clientSecret, idTokenSignedResponseAlg } = this.getOptions();
const oidc = await Issuer.discover(issuer); const oidc = await Issuer.discover(issuer);
return new oidc.Client({ return new oidc.Client({
client_id: clientId, client_id: clientId,
client_secret: clientSecret, client_secret: clientSecret,
id_token_signed_response_alg: idTokenSignedResponseAlg || 'RS256',
}); });
} }
@ -59,6 +61,7 @@ export class OIDCAuth extends BaseAuth {
const client = await this.createOIDCClient(); const client = await this.createOIDCClient();
const tokens = await client.callback(this.getRedirectUri(), { const tokens = await client.callback(this.getRedirectUri(), {
code: values.code, code: values.code,
iss: values.iss,
}); });
const userInfo: { [key: string]: any } = await client.userinfo(tokens.access_token); const userInfo: { [key: string]: any } = await client.userinfo(tokens.access_token);
const mappedUserInfo = this.mapField(userInfo); const mappedUserInfo = this.mapField(userInfo);

3772
yarn.lock

File diff suppressed because it is too large Load Diff