wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
 
import {
    Authority,
    AuthorityOptions,
    INetworkModule,
    IPerformanceClient,
    Logger,
} from "@azure/msal-common/browser";
import * as CustomAuthApiEndpoint from "./network_client/custom_auth_api/CustomAuthApiEndpoint.js";
import { buildUrl } from "./utils/UrlUtils.js";
import { BrowserConfiguration } from "../../config/Configuration.js";
import { BrowserCacheManager } from "../../cache/BrowserCacheManager.js";
 
/**
 * Authority class which can be used to create an authority object for Custom Auth features.
 */
export class CustomAuthAuthority extends Authority {
    /**
     * Constructor for the Custom Auth Authority.
     * @param authority - The authority URL for the authority.
     * @param networkInterface - The network interface implementation to make requests.
     * @param cacheManager - The cache manager.
     * @param authorityOptions - The options for the authority.
     * @param logger - The logger for the authority.
     * @param customAuthProxyDomain - The custom auth proxy domain.
     */
    constructor(
        authority: string,
        config: BrowserConfiguration,
        networkInterface: INetworkModule,
        cacheManager: BrowserCacheManager,
        logger: Logger,
        performanceClient: IPerformanceClient,
        private customAuthProxyDomain?: string
    ) {
        const ciamAuthorityUrl =
            CustomAuthAuthority.transformCIAMAuthority(authority);
 
        const authorityOptions: AuthorityOptions = {
            protocolMode: config.system.protocolMode,
            OIDCOptions: config.auth.OIDCOptions,
            knownAuthorities: config.auth.knownAuthorities,
            cloudDiscoveryMetadata: config.auth.cloudDiscoveryMetadata,
            authorityMetadata: config.auth.authorityMetadata,
        };
 
        super(
            ciamAuthorityUrl,
            networkInterface,
            cacheManager,
            authorityOptions,
            logger,
            "",
            performanceClient
        );
 
        // Set the metadata for the authority
        const metadataEntity = {
            aliases: [this.hostnameAndPort],
            preferred_cache: this.getPreferredCache(),
            preferred_network: this.hostnameAndPort,
            canonical_authority: this.canonicalAuthority,
            authorization_endpoint: "",
            token_endpoint: this.tokenEndpoint,
            end_session_endpoint: "",
            issuer: "",
            aliasesFromNetwork: false,
            endpointsFromNetwork: false,
            /*
             * give max value to make sure it doesn't expire,
             * as we only initiate the authority metadata entity once and it doesn't change
             */
            expiresAt: Number.MAX_SAFE_INTEGER,
            jwks_uri: "",
        };
        const cacheKey = this.cacheManager.generateAuthorityMetadataCacheKey(
            metadataEntity.preferred_cache,
            this.correlationId
        );
        cacheManager.setAuthorityMetadata(
            cacheKey,
            metadataEntity,
            this.correlationId
        );
    }
 
    /**
     * Gets the custom auth endpoint.
     * The open id configuration doesn't have the correct endpoint for the auth APIs.
     * We need to generate the endpoint manually based on the authority URL.
     * @returns The custom auth endpoint
     */
    getCustomAuthApiDomain(): string {
        /*
         * The customAuthProxyDomain is used to resolve the CORS issue when calling the auth APIs.
         * If the customAuthProxyDomain is not provided, we will generate the auth API domain based on the authority URL.
         */
        return !this.customAuthProxyDomain
            ? this.canonicalAuthority
            : this.customAuthProxyDomain;
    }
 
    override getPreferredCache(): string {
        return this.canonicalAuthorityUrlComponents.HostNameAndPort;
    }
 
    override get tokenEndpoint(): string {
        const endpointUrl = buildUrl(
            this.getCustomAuthApiDomain(),
            CustomAuthApiEndpoint.SIGNIN_TOKEN
        );
 
        return endpointUrl.href;
    }
}