簡體   English   中英

Angular 8 使用 ASP NET Core 3.1 Web Api 時的 CORS 策略問題

[英]CORS policy issue when consuming ASP NET Core 3.1 Web Api by Angular 8

我在開發 Angular 8、ASP NET Core Web Api Web 應用程序時遇到了 CORS 策略問題。 我的 angular 應用程序在 http://localhost:4200 上運行 為與 Web Api 通信創建了一項服務。 它看起來如下

@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {

  apiUrl: string = "";
 

  constructor(private http: HttpClient) {
 
    this.apiUrl = 'https://localhost:44316';
  }

 
  login(Username: any, Password: any){  
    return this.http.post<Observable<ResultItem<AuthenticationResponse>>>(this.apiUrl + "/api/User/Authenticate", {Username: Username, Password: Password});
  }
 
}

服務稍后在組件中調用,但它只是被注入,並與 subscribe 方法一起使用。

 onLogin(){  
    this.authenticationService.login(this.loginFormValues.username.value, this.loginFormValues.password.value).subscribe(
       result => {}); 
  }

Web Api 單獨運行,在 https://localhost:44316/ 上,從 Angular 調用的方法的端點如下所示:

[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    private readonly IUserService userService;

    public UserController(IUserService userService)
    {
        this.userService = userService;
    }


    [HttpPost("Authenticate")]
    public async Task<IActionResult> Authenticate(AuthenticationModel model)
    {
        return Ok(await userService.Login(model));
    }
}

我最關心的是我的啟動文件。 到目前為止,我已經嘗試在那里更改 CORS 設置,但沒有成功。 Startup.cs 文件的代碼如下所示。

快速說明:

ConfigureServices 方法中的兩行代碼使用了我的一些外部函數,它們的目的是:

  • AddSubstracture:將所有存儲庫注冊為瞬態並注冊 DbContext。

  • AddApplication:將存儲庫上一層的服務注冊為瞬態

Startup.cs 代碼如下所示

public class Startup
{
    private IServiceCollection _services;

    public Startup(IConfiguration configuration, IWebHostEnvironment environment)
    {
        Configuration = configuration;
        Environment = environment;
        SportFacilityUnitSettings = configuration.Get<SportFacilityUnitSettings>();
    }

    public IConfiguration Configuration { get; }
    public IWebHostEnvironment Environment { get; }
    public SportFacilityUnitSettings SportFacilityUnitSettings { get; }

    public void ConfigureServices(IServiceCollection services)
    {
         
        services.AddCors();
        services.AddMvc(option => option.EnableEndpointRouting = false);

        services.AddSubstructure(Configuration, Environment, SportFacilityUnitSettings);
        services.AddApplication(); 
        services.AddScoped<IPasswordHasher<User>, PasswordHasher<User>>();

        var appSettingsSection = Configuration.GetSection("AppSettings");
        services.Configure<AppSettings>(appSettingsSection);
         
        var appSettings = appSettingsSection.Get<AppSettings>();
        var key = Encoding.ASCII.GetBytes(appSettings.Secret);

        services.AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(x =>
        {
            x.RequireHttpsMetadata = false;
            x.SaveToken = true;
            x.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(key),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        }); 
        services.AddControllers().AddNewtonsoftJson(options =>
            options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

        services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
        services.AddHttpContextAccessor();

       
        _services = services;
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseCors(
         options => options.SetIsOriginAllowed(x => _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials()
     );
        app.UseMvc();
        app.UseHsts();
        app.UseMiddleware<JwtMiddleware>(); 
        app.UseAuthentication();
        app.UseRouting();  
        app.UseHttpsRedirection();  
        app.UseStaticFiles();
        app.UseAuthorization();  
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers(); 
        });

    }
}

當我點擊用於發送請求的登錄按鈕時,我在 Web 瀏覽器控制台中收到以下錯誤。

CORS 策略已阻止從源“http://localhost:4200”訪問“https://localhost:44316/api/User/Authenticate”處的 XMLHttpRequest:不存在“Access-Control-Allow-Origin”標頭在請求的資源上。

最奇怪的是,當我調試它並在 Api 層設置斷點時,調試器命中它,然后它進入服務層並在 Authentication method 內的某處失敗。

轉到托管您的應用程序的 IIS 並檢查您是否已正確設置以下信息。

#Step 1 : IIS --> HTTP 響應頭]

IIS HTTP 響應頭

#Step 2 ::在 IIS 下托管的 API 應用程序中設置 4 個字段設置 IIS 值

#Step 3:如果以上 2 個步驟不起作用,請確保您按照 msdn 信息為您的應用程序啟用 cors https://docs.microsoft.com/en-us/aspnet/core/security/cors?view= aspnetcore-3.1

步驟 4 ::調查您在 Web API 中使用的標頭信息,以及是否在您的 IIS 設置下允許(如步驟 1 中所述)

步驟 5 ::在您的身份驗證方法中放置一個斷點以查看失敗的位置和原因。 您也可以從此錯誤信息中獲得更多線索。

第 6 步:嘗試從前端啟用 CrossDomain 為 true。

第 7 步:嘗試為應用程序(調用應用程序和被調用應用程序)啟用 https

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM