Browse Source

Merge branch 'master' into imprv/97535-swrize-getPageTag

cao 3 years ago
parent
commit
4e69e8948c
1 changed files with 23 additions and 12 deletions
  1. 23 12
      packages/app/src/server/service/passport.ts

+ 23 - 12
packages/app/src/server/service/passport.ts

@@ -638,7 +638,7 @@ class PassportService implements S2sMessageHandlable {
       : configManager.getConfig('crowi', 'security:passport-oidc:callbackUrl'); // DEPRECATED: backward compatible with v3.2.3 and below
 
     // Prevent request timeout error on app init
-    const oidcIssuer = await this.getOIDCIssuerInstace(issuerHost);
+    const oidcIssuer = await this.getOIDCIssuerInstance(issuerHost);
     if (oidcIssuer != null) {
       logger.debug('Discovered issuer %s %O', oidcIssuer.issuer, oidcIssuer.metadata);
 
@@ -719,16 +719,26 @@ class PassportService implements S2sMessageHandlable {
 
   /**
    * Sanitize issuer Host / URL to match specified format
-   * Acceptable format : eg. https://hostname.com
+   * Acceptable formats :
+   * - https://hostname.com/auth/
+   * - domain only (hostname.com)
+   * - Full metadata url (https://hostname.com/auth/v2/.well-known/openid-configuration)
    * @param issuerHost string
-   * @returns string URL.origin
+   * @returns string URL/.well-known/openid-configuration
    */
-  getOIDCIssuerHostName(issuerHost) {
+  getOIDCMetadataURL(issuerHost: string) : string {
     const protocol = 'https://';
     const pattern = /^https?:\/\//i;
+    const metadataPath = '/.well-known/openid-configuration';
+    // If URL is full path with .well-known/openid-configuration
+    if (issuerHost.endsWith(metadataPath)) {
+      return issuerHost;
+    }
     // Set protocol if not available on url
     const absUrl = !pattern.test(issuerHost) ? `${protocol}${issuerHost}` : issuerHost;
-    return new URL(absUrl).origin;
+    const url = new URL(absUrl).href;
+    // Remove trailing slash if exists
+    return `${url.replace(/\/+$/, '')}${metadataPath}`;
   }
 
   /**
@@ -736,17 +746,17 @@ class PassportService implements S2sMessageHandlable {
  * Check and initialize connection to OIDC issuer host
  * Prevent request timeout error on app init
  *
- * @param issuerHost
+ * @param issuerHost string
  * @returns boolean
  */
-  async isOidcHostReachable(issuerHost) {
+  async isOidcHostReachable(issuerHost: string): Promise<boolean | undefined> {
     try {
-      const hostname = this.getOIDCIssuerHostName(issuerHost);
+      const metadataUrl = this.getOIDCMetadataURL(issuerHost);
       const client = require('axios').default;
       axiosRetry(client, {
         retries: 3,
       });
-      const response = await client.get(`${hostname}/.well-known/openid-configuration`);
+      const response = await client.get(metadataUrl);
       // Check for valid OIDC Issuer configuration
       if (!response.data.issuer) {
         logger.debug('OidcStrategy: Invalid OIDC Issuer configurations');
@@ -763,10 +773,10 @@ class PassportService implements S2sMessageHandlable {
    * Get oidcIssuer object
    * Utilize p-retry package to retry oidcIssuer initialization 3 times
    *
-   * @param issuerHost
+   * @param issuerHost string
    * @returns instance of OIDCIssuer
    */
-  async getOIDCIssuerInstace(issuerHost) {
+  async getOIDCIssuerInstance(issuerHost: string): Promise<void | OIDCIssuer> {
     const OIDC_TIMEOUT_MULTIPLIER = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:timeoutMultiplier');
     const OIDC_DISCOVERY_RETRIES = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:discoveryRetries');
     const OIDC_ISSUER_TIMEOUT_OPTION = await this.crowi.configManager.getConfig('crowi', 'security:passport-oidc:oidcIssuerTimeoutOption');
@@ -775,8 +785,9 @@ class PassportService implements S2sMessageHandlable {
       logger.error('OidcStrategy: setup failed');
       return;
     }
+    const metadataURL = this.getOIDCMetadataURL(issuerHost);
     const oidcIssuer = await pRetry(async() => {
-      return OIDCIssuer.discover(issuerHost);
+      return OIDCIssuer.discover(metadataURL);
     }, {
       onFailedAttempt: (error) => {
         // get current OIDCIssuer timeout options