@@ -178,38 +178,19 @@ private void ConfigureAspireDashboardResource(IResource dashboardResource)
178
178
{
179
179
context . EnvironmentVariables [ DashboardConfigNames . DashboardOtlpHttpUrlName . EnvVarName ] = otlpHttpEndpointUrl ;
180
180
181
- var model = context . ExecutionContext . ServiceProvider . GetRequiredService < DistributedApplicationModel > ( ) ;
182
- var allResourceEndpoints = model . Resources
183
- . Where ( r => ! string . Equals ( r . Name , KnownResourceNames . AspireDashboard , StringComparisons . ResourceName ) )
184
- . SelectMany ( r => r . Annotations )
185
- . OfType < EndpointAnnotation > ( )
186
- . ToList ( ) ;
187
-
188
- var corsOrigins = new HashSet < string > ( StringComparers . UrlHost ) ;
189
- foreach ( var endpoint in allResourceEndpoints )
190
- {
191
- if ( endpoint . UriScheme is "http" or "https" )
192
- {
193
- // Prefer allocated endpoint over EndpointAnnotation.Port.
194
- var origin = endpoint . AllocatedEndpoint ? . UriString ;
195
- var targetOrigin = ( endpoint . TargetPort != null )
196
- ? $ "{ endpoint . UriScheme } ://localhost:{ endpoint . TargetPort } "
197
- : null ;
181
+ // Use explicitly defined allowed origins if configured.
182
+ var allowedOrigins = configuration [ KnownConfigNames . DashboardCorsAllowedOrigins ] ;
198
183
199
- if ( origin != null )
200
- {
201
- corsOrigins . Add ( origin ) ;
202
- }
203
- if ( targetOrigin != null )
204
- {
205
- corsOrigins . Add ( targetOrigin ) ;
206
- }
207
- }
184
+ // If allowed origins are not configured then calculate allowed origins from endpoints.
185
+ if ( string . IsNullOrEmpty ( allowedOrigins ) )
186
+ {
187
+ var model = context . ExecutionContext . ServiceProvider . GetRequiredService < DistributedApplicationModel > ( ) ;
188
+ allowedOrigins = GetAllowedOriginsFromResourceEndpoints ( model ) ;
208
189
}
209
190
210
- if ( corsOrigins . Count > 0 )
191
+ if ( ! string . IsNullOrEmpty ( allowedOrigins ) )
211
192
{
212
- context . EnvironmentVariables [ DashboardConfigNames . DashboardOtlpCorsAllowedOriginsKeyName . EnvVarName ] = string . Join ( ',' , corsOrigins ) ;
193
+ context . EnvironmentVariables [ DashboardConfigNames . DashboardOtlpCorsAllowedOriginsKeyName . EnvVarName ] = allowedOrigins ;
213
194
context . EnvironmentVariables [ DashboardConfigNames . DashboardOtlpCorsAllowedHeadersKeyName . EnvVarName ] = "*" ;
214
195
}
215
196
}
@@ -266,6 +247,44 @@ private void ConfigureAspireDashboardResource(IResource dashboardResource)
266
247
} ) ) ;
267
248
}
268
249
250
+ private static string ? GetAllowedOriginsFromResourceEndpoints ( DistributedApplicationModel model )
251
+ {
252
+ var allResourceEndpoints = model . Resources
253
+ . Where ( r => ! string . Equals ( r . Name , KnownResourceNames . AspireDashboard , StringComparisons . ResourceName ) )
254
+ . SelectMany ( r => r . Annotations )
255
+ . OfType < EndpointAnnotation > ( )
256
+ . ToList ( ) ;
257
+
258
+ var corsOrigins = new HashSet < string > ( StringComparers . UrlHost ) ;
259
+ foreach ( var endpoint in allResourceEndpoints )
260
+ {
261
+ if ( endpoint . UriScheme is "http" or "https" )
262
+ {
263
+ // Prefer allocated endpoint over EndpointAnnotation.Port.
264
+ var origin = endpoint . AllocatedEndpoint ? . UriString ;
265
+ var targetOrigin = ( endpoint . TargetPort != null )
266
+ ? $ "{ endpoint . UriScheme } ://localhost:{ endpoint . TargetPort } "
267
+ : null ;
268
+
269
+ if ( origin != null )
270
+ {
271
+ corsOrigins . Add ( origin ) ;
272
+ }
273
+ if ( targetOrigin != null )
274
+ {
275
+ corsOrigins . Add ( targetOrigin ) ;
276
+ }
277
+ }
278
+ }
279
+
280
+ if ( corsOrigins . Count > 0 )
281
+ {
282
+ return string . Join ( ',' , corsOrigins ) ;
283
+ }
284
+
285
+ return null ;
286
+ }
287
+
269
288
private async Task WatchDashboardLogsAsync ( CancellationToken cancellationToken )
270
289
{
271
290
var loggerCache = new ConcurrentDictionary < string , ILogger > ( StringComparer . Ordinal ) ;
0 commit comments