Hello
I have an app in angular 2 that gets an access token from Identity server 4, after that i use the same token to get information about the user from the userinfo endpoint
i have no problems with the token endpoint but when i use the userinfo endpoint i get a 204 error and
XMLHttpRequest cannot load http://localhost:5000/connect/userinfo. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:52970' is therefore not allowed access.
anything i'm doing wrong or missed?
my startup http://pastebin.com/HSbwvC3v
and the calls i make from angular 2 http://pastebin.com/gbfvzT8V
if any more info needed just say
Have you configured that client's origin in the client configurations Allowed CORS Origin collection?
didn't had anything... right now it's like this http://pastebin.com/mYeiNT9g still same problem
Any update on the issue? closing for now - feel free to re-open if it needs further discussion.
Hi jjoaoclaro, I had the same problem, but solved it by adding AllowAnyMethod to .UseCors. Here is my .UseCors in Startup.Configure :
app.UseCors(builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
Hello @leastprivilege, hello @jjoaoclaro, we seem to be having the same issue. We have a very basic JS client that goes ahead and authenticates implicitly (meaning that XHRs on .well-known/openid-configuration and .well-known/openid-configuration/jwks are going through with expected response header access-control-allow-origin with a value from Client.AllowedCorsOrigins). Things start to fail when we (after being redirected back with access+id token) try to get connect/userinfo. No/some different CORS handling seem to happen for that endpoint.
In our Startup.cs we app.UseCors where we set a few headers and methods but we tried AllowAnyHeader and AllowAnyMethod as well. As soon as we manually/redundantly add WithOrigins things work as expected. We try to stay clear of @RasmusRummel 's suggestion of allowing any origin.
I tested this on 1.3.1.
Kind regards, Simon
This works for us - compare with the JS quickstart in the docs.
I'm having exactly the same issue using JS quickstart - the only difference to the docs is that js app is on a different domain than identity server.
Thank you @leastprivilege for the swift reply. I had a closer look at the JS quickstart and it looks like our own UseCors seemed to interfere with the CORS-handling setup by IdentityServer.
Maybe that helps others facing the same situation.
I am still not certain why it only fails for connect/userinfo but it is probably related to POST or the authorization header even though I set those in my CORS settings.
Is there any guidance (for or against) having another logical application (controllers configured differently from IdentityServer) hosted in combination with IdentityServer? This is where our initial CORS settings came from.
We use the built-in CORS plumbing yes: https://identityserver4.readthedocs.io/en/release/reference/options.html#cors
We have some placeholders in the docs for this guidance, but haven't had time to fill them in. In short, let us register the CORS middleware, and you just configure your policies in ConfigureServices. Give that a try and let us know how it works.
Hi folks, just run into a similar situation. All the suggestions so far havent worked for me.
tldr - make sure you lowercase your urls.
I found this thread the other day, where I had the same issue, could not access userinfo. Fun part was, it was only when I went to production...everything worked on my desktop, everything failed on the server.
Ultimately I disabled all cors checking in IdentityServer, and only relied on asp.net cors checking...still the same issue, worked at my desk, failed on the server.
Started reviewing asp.net cors code and found 'a something'.
I logged an issue with the asp.net cors people - https://github.com/aspnet/CORS/issues/124, they are doing StringComparer.OrdinalIgnoreCase in two out of three places, and a StringComparer.Ordinal in the last one.
In my appsettings.json for development I had:
"ServerOptions": {
"AllowedCorsOrigins": "http://localhost"
}
In production I had:
"ServerOptions": {
"AllowedCorsOrigins": "http://MyCoolProductionServer"
}
Once I lowercased MyCoolProductionServer everything worked as expected.
scopelt solution worked for me.
I've commented out the services.AddCors and app.UseCors and /userinfo started to return Access-Control-Allow-Origin
@brockallen and @leastprivilege. First, thanks for IdentityServer! Great stuff.
I am having the same issue reported above. The exact error is:
_Failed to load http://identityserver.mydomain.com/connect/userinfo: Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response._
Background.
NOTE: My applications work both locally while testing as well as on any machine within the same domain as the server where the applications 1. (web services with client app) and 2. (dentity server) are hosted.
To reiterate, it works on any machine within the same domain where the Production Server hosts the applications. While on any machine in that domain, I use same urls to go to my application as if I were navigating to it remotely. Remotely however is where my problem exists.
Project and Deployment Details:
1. Angular 6 Client hosted in www of web services application
2. http://www.mywebapp.mydomain.com -> Asp.Net Core 2 with full 4.7 framework for web services application- (Angular Client 6 client deploys to www here)
3. http://www.identityserver.mydomain.com -> Asp.Net Core 2 for Identity Server Application
I am using SQL Server and EntityFramework quickstart.
My ClientCorsOrigins table contains the following entry for my client
http://www.mywebapp.mydomain.com
Here are the steps that cause the error.
_ I would appreciate anyone's assistance on this. I will continue my own investigating and post the answer here if I find it first._
Here is the content of my IdentityServer application's Configure and ConfigureServices if that helps
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddIdentityServer()
.AddSigningCredential(new X509Certificate2(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"Resources\JABIdentityServer4Auth.pfx"), "mypassword"))
// Configures EF implementation of IClientStore, IResourceStore, and ICorsPolicyService with IdentityServer.
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(Config.ConnectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// Configures EF implementation of IPersistedGrantStore with IdentityServer.
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(Config.ConnectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 3600; // 1 Hour, also default value.
})
// Adds the resource owner validator, using Identity Server extension methods
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
// Adds the profile service, using Identity Server extension methods
.AddProfileService<ProfileService>();
services.AddAuthentication("SOME_COOKIE")
.AddCookie("SOME_COOKIE", options =>
{
options.ExpireTimeSpan = TimeSpan.FromHours(12);
})
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "http://identityserver.mydomain.com";
options.RequireHttpsMetadata = false;
options.ClientId = "some_client";
options.ResponseType = "code id_token"; // determines which grant is being used (hybrid here)
options.SaveTokens = true; // Save Access Token in cookie
// TODO: Don't think this is needed but verify.
options.Scope.Add("roles");
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role
};
});
services.AddDbContext<UserDbContext>(builder =>
builder.UseSqlServer(Config.ConnectionString, options => options.MigrationsAssembly(migrationsAssembly)));
services.AddDbContext<UserRoleDbContext>(builder =>
builder.UseSqlServer(Config.ConnectionString, options => options.MigrationsAssembly(migrationsAssembly)));
// Adds a scoped service of the type specified in serviceType with an implementation
// of the type specified in implementationType to the specified Microsoft.Extensions.DependencyInjection.IServiceCollection.
services.AddScoped<UserRepository>();
services.AddScoped<UserRoleRepository>();
services.AddScoped<UserStore>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
I had the same issue and the fix was adding the url to the client's "Allowed CORS Origins".
@EYScudeler, What did you add to the client's origins?
In my client (i.e. http://www.mywebapp.mydomain.com from explanation above) in
ConfigureServices I create this policy to allow identityserver to make requests against my client:
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://identityserver.mydomain.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
In Configure I add:
app.UseCors("default");
It does not seem that the error I am getting would require a cors policy by the client but rather a cors policy by the identity server. From the error posted above it looks like the Client is trying to call into IdentityServer, so it would be IdentityServer that needs to allow the origin from the client, which it does.
Also, unless I am missing something, it does not make sense that it works on other machines within the same domain where the applications are hosted and also on my local machine with my development setup, but not when I try to access the application from a machine outside of the domain using the same urls as when I am on the domain computers.
Update on my issue. I was getting this issue at my office. I am now home and when I tried it from here, it works. So, this leads me to believe that it is a firewall issue at my office. I will check this out tomorrow and confirm.
To be honest, I think many of us would agree, answers from you guys are just confusing and not helpful at all.
@billyjacobs2014 I think it was not a firewall. I have the same issue, but only in Firefox. in Chrome it works.
this helped for me:
[IdentityServer4] Startup.cs
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddCors(options =>
{
options.AddPolicy("api", policy =>
{
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
}
public void Configure(IApplicationBuilder app)
{
//...
app.UseCors("api");
}
.AllowAnyOrigin() on the Cors Policy looks like a work around.
IS4 registers a custom ICorsPolicyProvider. When you have multiple additional CORS policies in your system, make sure to add the middlewares for them after IS4 added its middleware.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseIdentityServer();
app.UseCors("mycustomcorspolicy");
...
}
That is important since the custom ICorsPolicyProvider by IS4 decorates the DefaultCorsPolicyProvider by ASP.NET. If the request is not for one of IS4's paths, it lets the decorated policy provider handle that request.
That means if the first middleware is not IS4's, then IS4's ICorsPolicyProvider asks the decorated provider, ASP.NET's ICorsPolicyProvider, to determine the fate of the request for IS4's paths. This leads to rejections like that of /connect/userinfo.
@halllo thanks this worked for me. I changed order it worked great.
@halllo Thank you. It helped. This is Something you wouldn't notice immediately.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
IS4 registers a custom ICorsPolicyProvider. When you have multiple additional CORS policies in your system, make sure to add the middlewares for them after IS4 added its middleware.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { ... app.UseIdentityServer(); app.UseCors("mycustomcorspolicy"); ... }That is important since the custom ICorsPolicyProvider by IS4 decorates the DefaultCorsPolicyProvider by ASP.NET. If the request is not for one of IS4's paths, it lets the decorated policy provider handle that request.
That means if the first middleware is not IS4's, then IS4's ICorsPolicyProvider asks the decorated provider, ASP.NET's ICorsPolicyProvider, to determine the fate of the request for IS4's paths. This leads to rejections like that of
/connect/userinfo.