Ich habe ein CORS-Problem in einer ASP.NET Web API 2-Anwendung mit OWIN-Authentifizierung (OAuth + JWT), die auf IIS gehostet wird.
Anfragen kommen von einem Angular-Frontend, aber CORS-Preflight-Anfragen (OPTIONS) schlagen fehl.
Was passiert
Browser sendet eine Preflight-OPTIONS-Anfrage
Der Server antwortet mit 405 / CORS-Fehler
Die tatsächliche API-Anfrage erreicht den Controller nie
Angular-Konsole zeigt CORS-Richtlinienblockierungsfehler an
Was ich bereits versucht habe
Ich habe bereits Änderungen in allen relevanten Ebenen vorgenommen, aber das Problem besteht weiterhin:
Startup.cs
Verwendet UseOAuthAuthorizationServer
UseJwtBearerAuthentication verwenden
Web-API über app.UseWebApi() hosten
WebApiConfig.cs
CORS mit EnableCorsAttribute aktiviert
Zulässige Ursprünge hinzugefügt über WhitelistUrls
namespace Pheonix.Web
{
public partial class Startup
{
//
// The Client ID is used by the application to uniquely identify itself to Azure AD.
// The Metadata Address is used by the application to retrieve the signing keys used by Azure AD.
// The AAD Instance is the instance of Azure, for example public Azure or Azure China.
// The Authority is the sign-in URL of the tenant.
// The Post Logout Redirect Uri is the URL where the user will be redirected after they sign out.
//
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
public void ConfigureAuth(IAppBuilder app)
{
ConfigureDbContext(app);
ConfigureCookieAuthentication(app);
//ConfigureGoogleAuth(app);
ConfigureOffice365Auth(app);
ConfigureJwtOAuth(app);
}
private static void ConfigureDbContext(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
app.CreatePerOwinContext(ApplicationSignInManager.Create);
}
private static void ConfigureJwtOAuth(IAppBuilder app)
{
app.UseOAuthAuthorizationServer(new AppOAuthOptions());
app.UseJwtBearerAuthentication(new AppJwtOptions());
HttpConfiguration config = new HttpConfiguration();
app.UseWebApi(config);
}
private static void ConfigureCookieAuthentication(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
CookieSecure = CookieSecureOption.Always,
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(
validateInterval: TimeSpan.FromMinutes(500000),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie))
}
});
}
private static void ConfigureGoogleAuth(IAppBuilder app)
{
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "200899829118-64tcj5ofov7iofnkbojs83tjb9bpnlr0.apps.googleusercontent.com",
ClientSecret = "IOMqL-RsFOGdYFniESnNgIdL"
});
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
}
private static void ConfigureOffice365Auth(IAppBuilder app)
{
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
RedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
}
}
});
}
}
public class AppOAuthOptions : OAuthAuthorizationServerOptions
{
public AppOAuthOptions()
{
TokenEndpointPath = new PathString("/token");
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(500000);
AccessTokenFormat = new AppJwtFormat(TimeSpan.FromMinutes(500000));
Provider = new AppOAuthProvider();
AllowInsecureHttp = true;
}
}
public class AppJwtFormat : ISecureDataFormat
{
private readonly TimeSpan _options;
public AppJwtFormat(TimeSpan options)
{
_options = options;
}
public string SignatureAlgorithm
{
get { return "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"; }
}
public string DigestAlgorithm
{
get { return "http://www.w3.org/2001/04/xmlenc#sha256"; }
}
public string Protect(AuthenticationTicket data)
{
if (data == null) throw new ArgumentNullException("data");
var issuer = "localhost";
var audience = "all";
var key = Convert.FromBase64String("bXlzdXBlcnN0cm9uZ2tleWZvckFwcFByb3RlY3Rpb24=");
var now = DateTime.UtcNow;
var expires = now.AddMinutes(_options.TotalMinutes);
var signingCredentials = new SigningCredentials(
new InMemorySymmetricSecurityKey(key),
SignatureAlgorithm,
DigestAlgorithm);
var token = new JwtSecurityToken(issuer, audience, data.Identity.Claims,
now, expires, signingCredentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
}
public class AppOAuthProvider : OAuthAuthorizationServerProvider
{
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var identity = new ClaimsIdentity();
var username = context.OwinContext.Get("username");
var employee_id = context.OwinContext.Get("employee_id");
var role = context.OwinContext.Get("role");
var country = context.OwinContext.Get("country");
identity.AddClaim(new Claim(ClaimTypes.Email, username));
identity.AddClaim(new Claim(ClaimTypes.PrimarySid, employee_id));
identity.AddClaim(new Claim(ClaimTypes.Role, role));
identity.AddClaim(new Claim(ClaimTypes.Country, country));
context.Validated(identity);
return Task.FromResult(0);
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
try
{
var username = context.Parameters["username"];
var employee_id = context.Parameters["employee_id"];
PhoenixEntities dbContext = new PhoenixEntities();
var user = dbContext.PersonEmployment.Where(x => x.OrganizationEmail == username.ToLower() && x.OrganizationEmail.Length > 0).First();// && x.IsEnabled == true);
if (user != null)
{
context.OwinContext.Set("username", username);
context.OwinContext.Set("employee_id", user.PersonID.ToString());
context.OwinContext.Set("role", user.Person.PersonInRole.Any() ? string.Join(",", user.Person.PersonInRole.Select(t => t.RoleID).ToList()) : "20" );// RS: update role by adding EDMS
context.OwinContext.Set("country", user.OfficeLocation.Value.ToString());
context.Validated();
}
else
{
context.SetError("Invalid credentials");
context.Rejected();
}
}
catch
{
context.SetError("Server error");
context.Rejected();
}
return Task.FromResult(0);
}
}
public class AppJwtOptions : JwtBearerAuthenticationOptions
{
public AppJwtOptions()
{
var issuer = "localhost";
var audience = "all";
var key = Convert.FromBase64String("bXlzdXBlcnN0cm9uZ2tleWZvckFwcFByb3RlY3Rpb24="); ;
AllowedAudiences = new[] { audience };
IssuerSecurityTokenProviders = new[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, key)
};
}
}
}
namespace Pheonix.Web
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
//config.EnableCors();
ApiAccess.Initialize();
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
//json.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat;
json.SerializerSettings.DateFormatString = "MM/dd/yyyy";// "mmm-dd-yyyy";
json.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
json.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
//json.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));
config.MessageHandlers.Add(new BlockOptionsHandler());
var corsAttr = new EnableCorsAttribute(ConfigurationManager.AppSettings["WhitelistUrls"], "*", "*");
config.EnableCors(corsAttr);
// Configure Web API to use only bearer token authentication.
// Commented as it was not making the Controllers Authorize.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
config.Services.Add(typeof(IExceptionLogger), new PheonixExceptionLogger());
config.Services.Replace(typeof(IExceptionHandler), new PheonixExceptionHandler());
// Web API routes
config.MapHttpAttributeRoutes();
UnityConfig.RegisterComponents();
MappingDTOModelToModel.Configure();
// Or any other way to fetch your container.
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
}
}
}
Ich habe ein CORS-Problem in einer ASP.NET Web API 2-Anwendung mit OWIN-Authentifizierung (OAuth + JWT), die auf IIS gehostet wird. Anfragen kommen von einem Angular-Frontend, aber CORS-Preflight-Anfragen (OPTIONS) schlagen fehl. Was passiert [list] [*]Browser sendet eine Preflight-OPTIONS-Anfrage [*]Der Server antwortet mit 405 / CORS-Fehler [*]Die tatsächliche API-Anfrage erreicht den Controller nie [*]Angular-Konsole zeigt CORS-Richtlinienblockierungsfehler an [/list] Was ich bereits versucht habe Ich habe bereits Änderungen in allen relevanten Ebenen vorgenommen, aber das [url=viewtopic.php?t=26065]Problem[/url] besteht weiterhin: Startup.cs [list] [*]Verwendet UseOAuthAuthorizationServer [*]UseJwtBearerAuthentication verwenden [*]Web-API über app.UseWebApi() hosten [/list] WebApiConfig.cs [list] [*]CORS mit EnableCorsAttribute aktiviert [*]Zulässige Ursprünge hinzugefügt über WhitelistUrls [*]Konfigurierte Routen und Filter />[*]Access-Control-Allow-*-Header hinzugefügt/entfernt [*]RequestFiltering-Einstellungen überprüft [*]Trotzdem schlägt CORS immer noch fehl, insbesondere während des Preflight. [/list] [code]namespace Pheonix.Web { public partial class Startup { // // The Client ID is used by the application to uniquely identify itself to Azure AD. // The Metadata Address is used by the application to retrieve the signing keys used by Azure AD. // The AAD Instance is the instance of Azure, for example public Azure or Azure China. // The Authority is the sign-in URL of the tenant. // The Post Logout Redirect Uri is the URL where the user will be redirected after they sign out. // private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"]; private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"]; private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"]; private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
HttpConfiguration config = new HttpConfiguration(); app.UseWebApi(config); }
private static void ConfigureCookieAuthentication(IAppBuilder app) { // Enable the application to use a cookie to store information for the signed in user // and to use a cookie to temporarily store information about a user logging in with a third party login provider app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), CookieSecure = CookieSecureOption.Always, Provider = new CookieAuthenticationProvider { // Enables the application to validate the security stamp when the user logs in. // This is a security feature which is used when you change a password or add an external login to your account. OnValidateIdentity = SecurityStampValidator.OnValidateIdentity( validateInterval: TimeSpan.FromMinutes(500000), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie)) }
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process. app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); }
public class AppOAuthOptions : OAuthAuthorizationServerOptions { public AppOAuthOptions() { TokenEndpointPath = new PathString("/token"); AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(500000); AccessTokenFormat = new AppJwtFormat(TimeSpan.FromMinutes(500000)); Provider = new AppOAuthProvider(); AllowInsecureHttp = true; } }
public class AppJwtFormat : ISecureDataFormat { private readonly TimeSpan _options;
public AppJwtFormat(TimeSpan options) { _options = options; }
public string SignatureAlgorithm { get { return "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"; } }
public string DigestAlgorithm { get { return "http://www.w3.org/2001/04/xmlenc#sha256"; } }
public string Protect(AuthenticationTicket data) { if (data == null) throw new ArgumentNullException("data");
var issuer = "localhost"; var audience = "all"; var key = Convert.FromBase64String("bXlzdXBlcnN0cm9uZ2tleWZvckFwcFByb3RlY3Rpb24="); var now = DateTime.UtcNow; var expires = now.AddMinutes(_options.TotalMinutes); var signingCredentials = new SigningCredentials( new InMemorySymmetricSecurityKey(key), SignatureAlgorithm, DigestAlgorithm); var token = new JwtSecurityToken(issuer, audience, data.Identity.Claims, now, expires, signingCredentials);
return new JwtSecurityTokenHandler().WriteToken(token); }
public AuthenticationTicket Unprotect(string protectedText) { throw new NotImplementedException(); } }
public class AppOAuthProvider : OAuthAuthorizationServerProvider { public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var identity = new ClaimsIdentity(); var username = context.OwinContext.Get("username"); var employee_id = context.OwinContext.Get("employee_id"); var role = context.OwinContext.Get("role"); var country = context.OwinContext.Get("country"); identity.AddClaim(new Claim(ClaimTypes.Email, username)); identity.AddClaim(new Claim(ClaimTypes.PrimarySid, employee_id)); identity.AddClaim(new Claim(ClaimTypes.Role, role)); identity.AddClaim(new Claim(ClaimTypes.Country, country));
public class AppJwtOptions : JwtBearerAuthenticationOptions { public AppJwtOptions() { var issuer = "localhost"; var audience = "all"; var key = Convert.FromBase64String("bXlzdXBlcnN0cm9uZ2tleWZvckFwcFByb3RlY3Rpb24="); ;
AllowedAudiences = new[] { audience }; IssuerSecurityTokenProviders = new[] { new SymmetricKeyIssuerSecurityTokenProvider(issuer, key) }; } } } [/code] [code]namespace Pheonix.Web { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services
GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));
config.MessageHandlers.Add(new BlockOptionsHandler()); var corsAttr = new EnableCorsAttribute(ConfigurationManager.AppSettings["WhitelistUrls"], "*", "*"); config.EnableCors(corsAttr);
// Configure Web API to use only bearer token authentication. // Commented as it was not making the Controllers Authorize. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); config.Services.Add(typeof(IExceptionLogger), new PheonixExceptionLogger()); config.Services.Replace(typeof(IExceptionHandler), new PheonixExceptionHandler());
// Web API routes config.MapHttpAttributeRoutes();
Ich entwickle eine auf Spring Boot Microservices basierende Anwendung, die über die übliche API-Schicht verfügt, die eine Verbindung zum Front-End herstellt und die Anforderungen an verschiedene...
Ich versuche, eine Anfrage von einer Winkelanwendung und einer ASP.NET -Web -API zu senden, die beide in Localhost auf zwei verschiedenen Ports ausgeführt werden. Beim Senden einer Anfrage von der...
Ich arbeite an einer Electron-App, die auf gehostet wird, und sie muss API-Anfragen an eine der folgenden Adressen stellen:
Localhost-API :
Wolke Funktion :
Ich verwende Express-JS in meiner Backend-Datei, in der ich die CORS-Richtlinie festgelegt habe. Aber nach der Bereitstellung der gesicherten Datei in Vercel kann ich auf meiner Clientseite keine...
Ich habe ein Backend in Java Spring 3.3.1, dies ist ein Multi -Mieter -Setup, was bedeutet, dass mehrere Frontenden auf das Backend zugreifen können. Meine erste React -Web -App funktioniert perfekt....