无法在ASP.NET Core中启用Identity Server 4的CORS

9

好的,我已经为我的.Net Core API添加了CORS策略,但是这些CORS策略在Identity Server 4端点上不起作用。 我有以下API,其中我尝试注册用户:

    [EnableCors("AllowAllCorsPolicy")]
    [Route("api/User")]
    public class UserController : Controller
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private IUserServices _userService;
        public UserController(UserManager<ApplicationUser> userManager, IUserServices userService)
        {
            _userManager = userManager;
            _userService = userService;
        }

        [HttpPost]
        public async Task<int> Post([FromBody]User userInfo)
        {
            var user = new ApplicationUser{  UserName = userInfo.Name, Email = userInfo.Email,
                UserTypeId = Constant.User, CustomerId = userInfo.CustomerId };

            //Follwing 3 lines give CORS issue.
            await _userManager.AddToRoleAsync(user, Constant.User);
            var userClaim = new Claim(Constant.User, user.Email.ToString(), ClaimValueTypes.Integer);
            await _userManager.AddClaimAsync(user, userClaim);

            // var userObj = _userService.AddNewUser(userInfo);
        }

现在,如果我使用上述身份验证服务器方法(AddToRoleAsync()AddClaimAsync()),我的客户端(运行在不同服务器上的angular应用程序)会出现CORS错误。
但是,如果我使用自定义方法注册用户,就不会出现CORS错误。
            //Don't get CORS error when commented below
            //await _userManager.AddToRoleAsync(user, Constant.User);
            //var userClaim = new Claim(Constant.User, user.Email.ToString(), ClaimValueTypes.Integer);
            //await _userManager.AddClaimAsync(user, userClaim);

            //use custom method
            var userObj = _userService.AddNewUser(userInfo);

为了在asp.net中启用CORS,我正在进行以下操作:在startup.cs中进行设置:
    public void ConfigureServices(IServiceCollection services)
            {
              services.AddCors(options =>
             {
                options.AddPolicy("AllowAllCorsPolicy",
                    builder => builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials());
            });
            services.AddMvc();
          }


public void Configure(IApplicationBuilder app, IHostingEnvironment env,  IServiceProvider serviceProvider)
        {
            app.UseCors("AllowAllCorsPolicy");
        }

我甚至尝试在startup.cs中手动添加CORS头文件,但是没有成功:

public void Configure(IApplicationBuilder app, IHostingEnvironment env,  IServiceProvider serviceProvider)
        {
            app.Use(async (context, next) =>
        {
            if (context.Request.Method == "OPTIONS")
                context.Response.StatusCode = (int)HttpStatusCode.OK;

            var headers = context.Response.Headers;
            if (headers.ContainsKey("Access-Control-Allow-Origin"))
            {
                headers["Access-Control-Allow-Origin"] = string.Join(",", context.Request.Headers["Referer"].Select(x => x.Substring(0, x.Length - 1)));
            }
            else
            {
                context.Response.Headers.Append("Access-Control-Allow-Origin", string.Join(",", context.Request.Headers["Referer"].Select(x => x.Substring(0, x.Length - 1))));
            }
            if (headers.ContainsKey("Access-Control-Allow-Headers"))
            {
                headers["Access-Control-Allow-Headers"] = "Origin, Content-Type, Accept, Client, Authorization, X-Auth-Token, X-Requested-With";
            }
            else
            {
                context.Response.Headers.Append("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Client, Authorization, X-Auth-Token, X-Requested-With");
            }
            if (headers.ContainsKey("Access-Control-Allow-Methods"))
            {
                headers["Access-Control-Allow-Credentials"] = "GET, POST, PATCH, PUT, DELETE, OPTIONS";
            }
            else
            {
                context.Response.Headers.Append("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
            }
            if (headers.ContainsKey("Access-Control-Allow-Credentials"))
            {
                headers["Access-Control-Allow-Credentials"] = "true";
            }
            else
            {
                context.Response.Headers.Append("Access-Control-Allow-Credentials", "true");
            }
            context.Response.Headers.Append("Access-Control-Expose-Headers", "X-Auth-Token");
            context.Response.Headers.Append("Vary", "Origin");
            await next();
        });
        }

我看到了这份文档,它提供了关于IdentityServer CORS选项的信息,并且还有这篇CORS文档,但帮助不是很大。


为什么你不使用 app.UseIdentityServerservices.AddIdentityServer - Dr Rob Lang
你的 IdentityServer 客户端是否已经正确定义? - Srikanth B
2个回答

11

这适用于服务器的较新版本。

    services.AddSingleton<ICorsPolicyService>((container) => {
        var logger = container.GetRequiredService<ILogger<DefaultCorsPolicyService>>();
        return new DefaultCorsPolicyService(logger)
        {
            AllowAll = true
        };
    });

更多详细信息请参考此讨论,原作者将得到相应的荣誉。

https://github.com/IdentityServer/IdentityServer4/issues/4685


1
我曾经遇到过这个问题,但奇怪的是只有在手机上出现(使用勇敢浏览器和火狐进行测试)。这对我来说已经修复了! - Alamakanambra

2
如果您正在使用IdentityServer 4与客户端进行身份验证,则必须使用IdentityServer 4配置CORS,详见:IdentityServer4CORS
IdentityServer4 CORS仅适用于令牌端点。您所做的是为所有控制器/方法配置CORS,这可能在您的情况下是正确的。但是,如果您不在identityserver4上启用CORS,则无法检索令牌。
您可以向客户端添加允许CORS的列表,这些列表将添加到identityserver数据库中,或者像这样添加全局默认值:
var cors = new DefaultCorsPolicyService(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
{
    AllowedOrigins = { "https://foo", "https://bar" }
};
services.AddSingleton<ICorsPolicyService>(cors);

请注意,您也可以手动将其添加到数据库中。

1
好的,如何在 .NET Core 3.0 中实现这个?_loggerFactory.CreateLogger 不再被支持。 - Тарас Красниця
@ТарасКрасниця 看起来是支持的: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.0 - Pilouk
3
在 ASP.NET Core 3.0 中,无法在 ConfigureServices 方法中添加 ILoggerFactory 参数。在 Startup.cs 和 Program.cs 中也不再支持注入 ILogger。详情请参见 链接。我已经找到了解决方案:services.AddSingleton<ICorsPolicyService, CustomCorsPolicyService>(); - Тарас Красниця
@ТарасКрасниця,您能否详细解释一下您对此问题的解决方案?我理解 AddSingleton 部分,但是您是如何实现 CustomCorsPolicyService 的呢?谢谢。 - Luigi
@ТарасКрасниця ILogger应该在StartUp构造函数中注入,如下所示-> public Startup(IConfiguration configuration, IWebHostEnvironment env, ILogger<Startup> logger)。创建一个变量,你就可以访问它了。 - Pilouk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接