IdentityServer3 -拒绝,因为无效的CORS路径

本文关键字:CORS 路径 无效 因为 拒绝 IdentityServer3 | 更新日期: 2023-09-27 18:07:10

我们有一个ASP。. NET MVC应用程序对IdentityServer3进行身份验证没有问题,但是使用ApiController的应用程序的web API部分开始失败,如果用户等待大约3分钟后再继续使用AJAX功能(在3分钟之前一切似乎都很好)。

在Chrome中看到的错误如下:

XMLHttpRequest无法加载https://test-auth.myauthapp.com/auth/connect/authorize?client_id=ecan-farmda...gwLTk5ZjMtN2QxZjUyMjgxNGE4MDg2NjFhZTAtOTEzNi00MDE3LTkzNGQtNTc5ODAzZTE1Mzgw。请求的文件中没有"Access-Control-Allow-Origin"标头资源。因此,不允许使用原产地"http://test.myapp.com"访问。

在IE上我得到以下错误:

SCRIPT7002: XMLHttpRequest: Network Error 0x4c7,该操作是被用户取消。

查看IdentityServer3的日志,我看到这样的条目:

2015-08-10 16:42[警告](Thinktecture.IdentityServer.Core.Configuration.Hosting.CorsPolicyProvider)CORS请求路径:/connect/authorization from originhttp://test.myapp.com但被拒绝,因为无效的CORS路径

在IdentityServer3 web应用程序中,我给客户端AllowedCorsOrigins:

Thinktecture.IdentityServer.Core.Models.Client client = new Thinktecture.IdentityServer.Core.Models.Client()
{
    Enabled = configClient.Enabled,
    ClientId = configClient.Id,
    ClientName = configClient.Name,
    RedirectUris = new List<string>(),
    PostLogoutRedirectUris = new List<string>(),
    AllowedCorsOrigins = new List<string>(),
    RequireConsent = false, // Don't show consents screen to user
    RefreshTokenExpiration = Thinktecture.IdentityServer.Core.Models.TokenExpiration.Sliding
};
foreach (Configuration.RegisteredUri uri in configClient.RedirectUris)
{
    client.RedirectUris.Add(uri.Uri);
}
foreach (Configuration.RegisteredUri uri in configClient.PostLogoutRedirectUris)
{
    client.PostLogoutRedirectUris.Add(uri.Uri);
}
// Quick hack to try and get CORS working
client.AllowedCorsOrigins.Add("http://test.myapp.com");
client.AllowedCorsOrigins.Add("http://test.myapp.com/"); // Don't think trailing / needed, but added just in case
clients.Add(client);

注册服务时,我添加了InMemoryCorsPolicyService:

app.Map("/auth", idsrvApp =>
{
    var factory = new IdentityServerServiceFactory();
    factory.Register(new Registration<AuthContext>(resolver => AuthObjects.AuthContext));
    factory.Register(new Registration<AuthUserStore>());
    factory.Register(new Registration<AuthRoleStore>());
    factory.Register(new Registration<AuthUserManager>());
    factory.Register(new Registration<AuthRoleManager>());
    // Custom user service used to inject custom registration workflow
    factory.UserService = new Registration<IUserService>(resolver => AuthObjects.AuthUserService);
    var scopeStore = new InMemoryScopeStore(Scopes.Get());
    factory.ScopeStore = new Registration<IScopeStore>(scopeStore);
    var clientStore = new InMemoryClientStore(Clients.Get());
    factory.ClientStore = new Registration<IClientStore>(clientStore);
    var cors = new InMemoryCorsPolicyService(Clients.Get());
    factory.CorsPolicyService = new Registration<ICorsPolicyService>(cors);
    ...
    var options = new IdentityServerOptions
    {
        SiteName = "Authentication",
        SigningCertificate = LoadCertificate(),
        Factory = factory,
        AuthenticationOptions = authOptions
    };
    ...
});

我注意到IdentityServer3日志条目说"为path:/connect/authorize发出的CORS请求"而不是"为path:/auth/connect/authorize发出的CORS请求"。但是查看IdentityServer3源代码表明这可能不是问题。

也许InMemoryCorsPolicyService没有被拾取?

有什么想法,为什么事情不工作的AJAX称为ApiController?

Thinktecture。已使用NuGet安装IdevtityServer3 v1.6.2。

我正在与IdentityServer3开发人员进行对话,但我仍然有一个问题达到解决方案。如果有帮助的话:

https://github.com/IdentityServer/IdentityServer3/issues/1697

IdentityServer3 -拒绝,因为无效的CORS路径

您是否也尝试添加https url ?——client.AllowedCorsOrigins.Add("https://test.myapp.com";

IdentityServer的文档说你应该在客户端配置它:

AllowedCorsOrigins =…//默认为发现、用户信息、令牌和撤销端点。

https://docs.duendesoftware.com/identityserver/v6/reference/options/歌珥

CORS是一场噩梦!这是浏览器的问题,这就是为什么你在IE和Chrome中看到不同的行为。

在服务器上配置CORS(至少)有两种方式。当客户端使用Origin头发出请求时,您必须告诉服务器是否接受它-如果接受,则服务器将Access-Control-Allow-Origin头添加到浏览器的响应中。

在MVC/webAPI中,你必须添加CORS服务,设置CORS策略,然后.UseCors像这样:

builder.Services.AddCors((options =>
            {
                if (settings.AllowedCorsOrigins.Length > 0)
                {
                    options.AddDefaultPolicy(builder => 
                    { 
                        builder.SetIsOriginAllowedToAllowWildcardSubdomains();
                        builder.AllowAnyHeader().AllowAnyMethod().WithOrigins(settings.AllowedCorsOrigins); 
                    });
                }
                if (isDevelopment)
                {
                    options.AddPolicy("localhost", builder => 
                    {
                        builder.SetIsOriginAllowedToAllowWildcardSubdomains();
                        builder.AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowed((string origin) => { return origin.Contains("localhost"); }); });
                    }
            });

            app.UseCors();
            if (app.Environment.IsDevelopment())
            {
                app.UseCors("localhost");
            }

通常,您希望允许的主机列表作为appsettings.json中的字符串数组。注意SetIsOriginAllowedToAllowWildcardSubdomains的陷阱。

除此之外,IdentityServer还有自己的额外CORS设置,这些设置除了之外还应用于标准MVC/webAPI设置。这些都在ClientCorsOrigin表中,这不支持通配符子域。您可以通过实现自己的ICorsPolicyService来避开这个陷阱,使用与appsettings.json相同的设置,例如
    public class CorsPolicyService : ICorsPolicyService
    {
        private readonly CorsOptions _options;
        public CorsPolicyService(IOptions<CorsOptions> options)
        {
            _options = options.Value;
        }
        private bool CheckHost(string host)
        {
            foreach (string p in _options.AllowedCorsOrigins)
            {
                if (Regex.IsMatch(host, Regex.Escape(p).Replace("''*", "[a-zA-Z0-9]+"))) // Hyphen?
                {
                    return true;
                }
            }
            return false;
        }
        public Task<bool> IsOriginAllowedAsync(string origin)
        {
            return Task.FromResult(CheckHost(origin));
        }
    }

允许Cors策略添加到你的Startup.cs文件

代码
services.AddCors(options =>
{
options.AddDefaultPolicy(
                  builder =>
                  {
                      builder.WithOrigins("https://localhost:44343") //replace with your localhost 
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                  });
                  });