IdentityServer3 - 由于 CORS 路径无效而被拒绝

问题描述 投票:0回答:4

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

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:网络错误0x4c7,操作是 被用户取消。

查看 IdentityServer3 的日志,我看到如下条目:

2015-08-10 16:42 [警告] (Thinktecture.IdentityServer.Core.Configuration.Hosting.CorsPolicyProvider) 对路径发出的 CORS 请求:/connect/authorize 来自源: http://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 日志条目显示“针对路径发出的 CORS 请求:/connect/authorize”,而不是“针对路径发出的 CORS 请求:/auth/connect/authorize”。但查看 IdentityServer3 源代码表明这可能不是问题所在。

也许 InMemoryCorsPolicyService 没有被拾取?

对于为什么 AJAX 的 ApiController 不起作用有什么想法吗?

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

更新

我正在与 IdentityServer3 开发人员进行对话,但仍有问题需要解决。如果有帮助:

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

c# ajax cors asp.net-apicontroller identityserver3
4个回答
0
投票

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


0
投票

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

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

https://docs.duendesoftware.com/identityserver/v6/reference/options/#cors


0
投票

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));
        }
    }


0
投票

要允许 Cors 策略,请将其添加到您的 Startup.cs 文件中。

代码

services.AddCors(options =>
{
options.AddDefaultPolicy(
                  builder =>
                  {
                      builder.WithOrigins("https://localhost:44343") //replace with your localhost 
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                  });
                  });
© www.soinside.com 2019 - 2024. All rights reserved.