OIDC: Check static client registration and add login flow (#11088)
* util functions to get static client id * check static client ids in login flow * remove dead code * add trailing slash * comment error enum * spacing * PR tidying * more comments * add ValidatedDelegatedAuthConfig type * Update src/Login.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update src/Login.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update src/utils/ValidatedServerConfig.ts Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * rename oidc_static_clients to oidc_static_client_ids * comment --------- Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
parent
35f8c525aa
commit
328db8fdfd
10 changed files with 456 additions and 45 deletions
|
@ -16,14 +16,13 @@ limitations under the License.
|
|||
|
||||
import React, { ReactNode } from "react";
|
||||
import { AutoDiscovery, ClientConfig } from "matrix-js-sdk/src/autodiscovery";
|
||||
import { IDelegatedAuthConfig, M_AUTHENTICATION } from "matrix-js-sdk/src/client";
|
||||
import { M_AUTHENTICATION } from "matrix-js-sdk/src/client";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { IClientWellKnown } from "matrix-js-sdk/src/matrix";
|
||||
import { ValidatedIssuerConfig } from "matrix-js-sdk/src/oidc/validate";
|
||||
|
||||
import { _t, UserFriendlyError } from "../languageHandler";
|
||||
import SdkConfig from "../SdkConfig";
|
||||
import { ValidatedServerConfig } from "./ValidatedServerConfig";
|
||||
import { ValidatedDelegatedAuthConfig, ValidatedServerConfig } from "./ValidatedServerConfig";
|
||||
|
||||
const LIVELINESS_DISCOVERY_ERRORS: string[] = [
|
||||
AutoDiscovery.ERROR_INVALID_HOMESERVER,
|
||||
|
@ -266,14 +265,14 @@ export default class AutoDiscoveryUtils {
|
|||
if (discoveryResult[M_AUTHENTICATION.stable!]?.state === AutoDiscovery.SUCCESS) {
|
||||
const { authorizationEndpoint, registrationEndpoint, tokenEndpoint, account, issuer } = discoveryResult[
|
||||
M_AUTHENTICATION.stable!
|
||||
] as IDelegatedAuthConfig & ValidatedIssuerConfig;
|
||||
delegatedAuthentication = {
|
||||
] as ValidatedDelegatedAuthConfig;
|
||||
delegatedAuthentication = Object.freeze({
|
||||
authorizationEndpoint,
|
||||
registrationEndpoint,
|
||||
tokenEndpoint,
|
||||
account,
|
||||
issuer,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -17,6 +17,8 @@ limitations under the License.
|
|||
import { IDelegatedAuthConfig } from "matrix-js-sdk/src/client";
|
||||
import { ValidatedIssuerConfig } from "matrix-js-sdk/src/oidc/validate";
|
||||
|
||||
export type ValidatedDelegatedAuthConfig = IDelegatedAuthConfig & ValidatedIssuerConfig;
|
||||
|
||||
export interface ValidatedServerConfig {
|
||||
hsUrl: string;
|
||||
hsName: string;
|
||||
|
@ -30,5 +32,11 @@ export interface ValidatedServerConfig {
|
|||
|
||||
warning: string | Error;
|
||||
|
||||
delegatedAuthentication?: IDelegatedAuthConfig & ValidatedIssuerConfig;
|
||||
/**
|
||||
* Config related to delegated authentication
|
||||
* Included when delegated auth is configured and valid, otherwise undefined
|
||||
* From homeserver .well-known m.authentication, and issuer's .well-known/openid-configuration
|
||||
* Used for OIDC native flow authentication
|
||||
*/
|
||||
delegatedAuthentication?: ValidatedDelegatedAuthConfig;
|
||||
}
|
||||
|
|
24
src/utils/oidc/error.ts
Normal file
24
src/utils/oidc/error.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* OIDC error strings, intended for logging
|
||||
*/
|
||||
export enum OidcClientError {
|
||||
DynamicRegistrationNotSupported = "Dynamic registration not supported",
|
||||
DynamicRegistrationFailed = "Dynamic registration failed",
|
||||
DynamicRegistrationInvalid = "Dynamic registration invalid response",
|
||||
}
|
60
src/utils/oidc/registerClient.ts
Normal file
60
src/utils/oidc/registerClient.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { ValidatedDelegatedAuthConfig } from "../ValidatedServerConfig";
|
||||
import { OidcClientError } from "./error";
|
||||
|
||||
/**
|
||||
* Get the statically configured clientId for the issuer
|
||||
* @param issuer delegated auth OIDC issuer
|
||||
* @param staticOidcClients static client config from config.json
|
||||
* @returns clientId if found, otherwise undefined
|
||||
*/
|
||||
const getStaticOidcClientId = (issuer: string, staticOidcClients?: Record<string, string>): string | undefined => {
|
||||
// static_oidc_clients are configured with a trailing slash
|
||||
const issuerWithTrailingSlash = issuer.endsWith("/") ? issuer : issuer + "/";
|
||||
return staticOidcClients?.[issuerWithTrailingSlash];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the clientId for an OIDC OP
|
||||
* Checks statically configured clientIds first
|
||||
* @param delegatedAuthConfig Auth config from ValidatedServerConfig
|
||||
* @param clientName Client name to register with the OP, eg 'Element'
|
||||
* @param baseUrl URL of the home page of the Client, eg 'https://app.element.io/'
|
||||
* @param staticOidcClients static client config from config.json
|
||||
* @returns Promise<string> resolves with clientId
|
||||
* @throws if no clientId is found
|
||||
*/
|
||||
export const getOidcClientId = async (
|
||||
delegatedAuthConfig: ValidatedDelegatedAuthConfig,
|
||||
// these are used in the following PR
|
||||
_clientName: string,
|
||||
_baseUrl: string,
|
||||
staticOidcClients?: Record<string, string>,
|
||||
): Promise<string> => {
|
||||
const staticClientId = getStaticOidcClientId(delegatedAuthConfig.issuer, staticOidcClients);
|
||||
if (staticClientId) {
|
||||
logger.debug(`Using static clientId for issuer ${delegatedAuthConfig.issuer}`);
|
||||
return staticClientId;
|
||||
}
|
||||
|
||||
// TODO attempt dynamic registration
|
||||
logger.error("Dynamic registration not yet implemented.");
|
||||
throw new Error(OidcClientError.DynamicRegistrationNotSupported);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue