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您是否也尝试添加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
的陷阱。
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();
});
});