Skip to main content

configure-cors

Configure CORS (browser cross-origin access) for an ABP HTTP API host. USE FOR: the App:CorsOrigins setting (comma-separated, trailing-slash trimming), AddCors + WithOrigins, WithAbpExposedHeaders, SetIsOriginAllowedToAllowWildcardSubdomains for wildcard subdomains, the AllowCredentials vs any-origin conflict, UseCors middleware ordering, and which host/gateway to configure in tiered/microservice solutions. DO NOT USE FOR: OpenIddict client redirect / post-logout URIs (registered on the OpenIddict client application at creation/seeding, not a CORS or auth-config setting); RedirectAllowedUrls and named app URLs (configure-app-urls); CSRF/antiforgery and security response headers (secure-web-requests); calling a remote API from C# (consume-remote-services).

الانتقال إلى التثبيت

معلومات المصدر

المستودع
abpframework/abp-skills
آخر نشاط في المصدر
٢٠ يوليو ٢٠٢٦ في ٠٣:٢٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٨
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
configure-cors
description
Configure CORS (browser cross-origin access) for an ABP HTTP API host. USE FOR: the App:CorsOrigins setting (comma-separated, trailing-slash trimming), AddCors + WithOrigins, WithAbpExposedHeaders, SetIsOriginAllowedToAllowWildcardSubdomains for wildcard subdomains, the AllowCredentials vs any-origin conflict, UseCors middleware ordering, and which host/gateway to configure in tiered/microservice solutions. DO NOT USE FOR: OpenIddict client redirect / post-logout URIs (registered on the OpenIddict client application at creation/seeding, not a CORS or auth-config setting); RedirectAllowedUrls and named app URLs (configure-app-urls); CSRF/antiforgery and security response headers (secure-web-requests); calling a remote API from C# (consume-remote-services).
license
MIT
# Configure CORS in ABP CORS controls which **browser origins** (scheme + host + port) are allowed to call your HTTP API from client-side JavaScript. In ABP you configure it on the **API host** (the `HttpApi.Host` project), using ASP.NET Core's CORS with one ABP-specific helper (`WithAbpExposedHeaders`). The allowed origins come from the `App:CorsOrigins` setting. This is **not** the same as OpenIddict redirect URIs, `AppUrlOptions`, or `RedirectAllowedUrls` — see *When Not to Use*. ## When to Use - A browser SPA (Angular/React/Blazor WASM) or another site calls your ABP API and the browser blocks it with a CORS error. - Adding/removing allowed origins, or supporting wildcard subdomains. - Getting `UseCors` into the pipeline in the right order. - Deciding where CORS goes in a tiered or microservice solution (API host vs gateway). ## When Not to Use - **OpenIddict allowed redirect / post-logout URIs** for the OAuth flow — these are the OpenIddict **client application's** registered URIs (set when the client/application is created or seeded), not a CORS setting. (A login redirect failing is not a CORS problem.) - **`AppUrlOptions` named app URLs and `RedirectAllowedUrls`** (server-side redirect allow-list) — use the **configure-app-urls** skill. - **Antiforgery/CSRF and security response headers** (CSP etc.) — use the **secure-web-requests** skill. - **Calling a remote HTTP API from C#** (no browser, no CORS) — use the **consume-remote-services** skill. ## 1. Allowed origins: `App:CorsOrigins` The startup templates read allowed origins from the `App:CorsOrigins` setting — a **comma-separated** list of origins (no trailing path), in `appsettings.json`: ```json { "App": { "CorsOrigins": "https://*.example.com,http://localhost:4200,https://localhost:44307" } } ``` - Each entry is a full **origin**: scheme + host + optional port. `http://localhost:4200` and `https://localhost:4200` are different origins; so are different ports. - A leading `*.` in the host (e.g. `https://*.example.com`) marks a **wildcard subdomain** (see step 2). - The template splits on `,` (removing empty entries) and trims a trailing `/` from each entry (`RemovePostFix("/")`), because a trailing slash makes the origin string not match the browser's `Origin` header. ## 2. The CORS policy The template's `ConfigureCors` builds a default policy from `App:CorsOrigins`: ```csharp context.Services.AddCors(options => { options.AddDefaultPolicy(builder => { builder .WithOrigins( configuration["App:CorsOrigins"]? .Split(",", StringSplitOptions.RemoveEmptyEntries) .Select(o => o.RemovePostFix("/")) .ToArray() ?? Array.Empty<string>()) .WithAbpExposedHeaders() // ABP: exposes ABP's response headers to the browser .SetIsOriginAllowedToAllowWildcardSubdomains() // makes https://*.example.com match subdomains .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // only if the browser sends credentials (cookies, HTTP auth, client certs, or fetch credentials: 'include') }); }); ``` - **`WithAbpExposedHeaders()`** is the only ABP-specific call — it adds ABP's framework response headers, the error-format header (`_AbpErrorFormat`) and the tenant-resolution-error header (`Abp-Tenant-Resolve-Error`), to `Access-Control-Expose-Headers` so browser code can read them. Everything else is plain ASP.NET Core CORS. - **`SetIsOriginAllowedToAllowWildcardSubdomains()`** is what makes a `https://*.example.com` entry actually match `https://tenant1.example.com`. Without it, the wildcard entry never matches. ## 3. Middleware order — `UseCors` Add `app.UseCors()` in `OnApplicationInitialization`, **after `UseRouting()` and before `UseAuthentication()`/`UseAuthorization()`**. If it runs too late (after auth) or before routing, preflight requests don't get the CORS headers and the browser blocks the call. The startup template already places it correctly. ## 4. Credentials vs. any origin `AllowCredentials()` is needed only when the browser sends credentials — cookies, HTTP authentication, client certificates, or `fetch(..., { credentials: 'include' })` (an explicit `Authorization` header alone doesn't require it; that's just an allowed request header). It **cannot** be combined with a wildcard `*` origin — the browser rejects `Access-Control-Allow-Origin: *` together with credentials. That's why the template lists explicit origins (and uses wildcard *subdomains* of a named domain, not `*`). If you don't need credentials, you can loosen origins; if you do, enumerate the exact origins. ## 5. Tiered / microservice solutions CORS must be configured on **whatever the browser talks to directly**: - **Layered/tiered app:** the `HttpApi.Host` (and the AuthServer if the SPA hits it directly for the OAuth flow). - **Microservice solution:** the **API gateway** the SPA calls, plus any service exposed directly to the browser. Individual back-end microservices reached only through the gateway don't need browser CORS. ## Validation - Reproduce the browser's **preflight**: an `OPTIONS` request to your API with `Origin: <spa-origin>` and `Access-Control-Request-Method: POST` should return `204` with `Access-Control-Allow-Origin: <spa-origin>` (and `Access-Control-Allow-Credentials: true` when credentials are on). Check the actual response headers, not just `appsettings.json`. - If the origin is missing from the response, the entry doesn't match — check scheme/port and the trailing slash. ## Common Pitfalls - **Trailing slash** in an origin (`https://example.com/`) — it won't match the browser `Origin` header; drop it (the template's `RemovePostFix("/")` does this for `App:CorsOrigins`). - **Wildcard subdomain without `SetIsOriginAllowedToAllowWildcardSubdomains()`** — `https://*.example.com` silently never matches. - **`AllowCredentials()` with a `*` origin** — rejected by the browser; enumerate origins or a named wildcard-subdomain domain. - **Wrong `UseCors` order** — must be after `UseRouting`, before `UseAuthentication`. - **Different port/scheme** counts as a different origin — add each SPA dev/prod origin explicitly. - **Confusing CORS with the OAuth redirect** — a failed login redirect is an OpenIddict client redirect-URI issue (fix the client application's registered redirect URIs, set at client creation/seeding), not CORS.
عرض على GitHub