実現したいこと
開発環境においてCORSエラーを回避したい
発生している問題・分からないこと
Angular, ASP.NET Core Web API, Keycloakを用いたSAML2認証を組み合わせたアプリケーションにおいてCORSのエラーが発生しています。どうすれば回避できるのでしょうか?
エラーメッセージ中の以下のアドレスは次に対応します。
https://localhost:4200 : フロントエンド側(Angular)のアドレス
https://localhost:7055 : バックエンド側(ASP.NET Core Web API)のアドレス
https://localhost:8443 : Keycloakのアドレス
エラーメッセージ
error
1Access to XMLHttpRequest at 'https://localhost:8443/realms/(realm name)/protocol/saml?SAMLRequest=fJFNa8MwDIbvhf4H43tnx%2FloKpJAWBkUukuz7rCbk7ok4NiZ5ezj3y%2Ft2rHB6EUHSY%2F0vlKGstdigHL0rdmp11GhJx%2B9NgjflZyOzoCV2CEY2SsE30BVPm5B3HEYnPW2sZr%2BZm4jElE531lDyWad0%2B5QcyGSY5MeQnWMgiCp64Qn6TJK60REqyCg5Fk5nICcTvxEIY5qY9BL46cUF9GCrxY8eQo4xCEE4oWS9WSjM%2FK0Jqet9wMCY9o2UrcWPaRRFDKnpO6RVZ%2F4oO07u1phJw%2BUlFeZ99bg2CtXKffWNWq%2F2%2F43ccnjmFUn95dYNkiL%2BYyQ7HwTOKt2xS0yO6%2F%2BaZ3PLom%2F3ym%2BAAAA%2F%2F8DAA%3D%3D&RelayState=fHLe6EsBVGLe6Gh3cn9mzROQ' (redirected from 'https://localhost:7055/account/UserInfo') from origin 'https://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
該当のソースコード
Program.cs(前半部分)
1 2var builder = WebApplication.CreateBuilder(args); 3 4builder.Services.AddLogging(loggingBuilder => 5{ 6 loggingBuilder.AddConsole(); 7 loggingBuilder.AddDebug(); 8 loggingBuilder.SetMinimumLevel(LogLevel.Debug); 9}); 10 11#if DEBUG 12// CORSの有効化(開発時のみ) 13var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 14 15builder.Services.AddCors(options => 16{ 17 options.AddPolicy(name: MyAllowSpecificOrigins, 18 policy => 19 { 20 policy.WithOrigins("https://localhost:4200", "https://localhost:8443") 21 .AllowAnyHeader() 22 .AllowAnyMethod(); 23 }); 24}); 25#endif 26 27// Add services to the container. 28 29// 分散キャッシュの設定 30builder.Services.AddDistributedPostgreSqlCache(options => 31{ 32 options.ConnectionString = builder.Configuration.GetConnectionString("FlowDb"); 33 options.SchemaName = "public"; 34 options.TableName = "TestCache"; 35 options.DisableRemoveExpired = false; 36 options.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30); 37}); 38 39builder.Services.AddAuthentication(options => 40{ 41 options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; 42 options.DefaultChallengeScheme = Saml2Defaults.Scheme; 43}) 44.AddCookie() 45.AddSaml2(options => 46{ 47 var entityId = builder.Configuration["Saml2:entityId"]; 48 var idpEntityId = builder.Configuration["Saml2:idpEntityId"]; 49 var metadataUrl = builder.Configuration["Saml2:IdpMetadataURL"]; 50 51 options.SPOptions.EntityId = new Sustainsys.Saml2.Metadata.EntityId(entityId); 52 options.SPOptions.AuthenticateRequestSigningBehavior = Sustainsys.Saml2.Configuration.SigningBehavior.Never; 53 options.SPOptions.PublicOrigin = new(entityId ?? String.Empty); 54 var idp = new Sustainsys.Saml2.IdentityProvider( 55 new Sustainsys.Saml2.Metadata.EntityId(idpEntityId), 56 options.SPOptions) 57 { 58 MetadataLocation = metadataUrl, 59 LoadMetadata = true, 60 }; 61 options.IdentityProviders.Add(idp); 62}); 63 64builder.Services.AddAuthorization(options => 65{ 66 options.AddPolicy("Saml2", policy => 67 { 68 policy.RequireClaim(ClaimTypes.NameIdentifier); 69 }); 70}); 71 72builder.Services.AddControllers(); 73builder.Services.AddSession(options => 74{ 75 options.IdleTimeout = TimeSpan.FromMinutes(30); 76 options.Cookie.HttpOnly = true; 77 options.Cookie.IsEssential = true; 78});
Program.cs
1 2var app = builder.Build(); 3 4// Configure the HTTP request pipeline. 5 6app.UseHttpsRedirection(); 7app.UseSession(); 8 9#if DEBUG 10// CORSの有効化(開発時のみ) 11app.UseCors(MyAllowSpecificOrigins); 12#endif 13 14app.UseAuthentication(); 15app.UseAuthorization(); 16 17app.MapControllers(); 18 19app.Run();
http.service.ts
1import { HttpClient, HttpHeaders } from '@angular/common/http'; 2import { Injectable } from '@angular/core'; 3import { Observable } from 'rxjs'; 4import { Endpoints } from '../constants/endpoints'; 5 6@Injectable({ 7 providedIn: 'root' 8}) 9export class HttpService { 10 11 constructor(private http: HttpClient) { } 12 13 get<T>(endpoint: string): Observable<T> { 14 const httpOptions = { 15 headers: new HttpHeaders({ 16 'Access-Control-Allow-Origin': '*', 17 }) 18 }; 19 20 return this.http.get<T>(Endpoints.getUrl(endpoint), httpOptions); 21 } 22 23 post<T>(endpoint: string, body: any | null): Observable<T> { 24 const httpOptions = { 25 headers: new HttpHeaders({ 26 'Access-Control-Allow-Origin': '*', 27 }) 28 }; 29 30 return this.http.post<T>(Endpoints.getUrl(endpoint), body, httpOptions); 31 } 32} 33
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
検索結果に従ってAngularからのHTTP GETのヘッダーに'Access-Control-Allow-Origin': '*'を追加したり、ASP.NET Core Web API側にAddCorsメソッドとUseCorsメソッドの呼び出しも追加しましたが解消できていません。
補足
バージョンは以下の通りです
.NET: 8
Angular: 18
Keycloak: 25
Keycloakでは、Valid redirect URIsに「https://localhost:7055/*」と「https://localhost:4200/*」を指定しています。
回答1件
あなたの回答
tips
プレビュー