我无法使用owin中间件保护我的Web API。
我已经安装了以下包
Install-Package Microsoft.Owin.Cors -Version 2.1.0
以下是ConfigureAuth.cs代码。
public void ConfigureAuth(IAppBuilder app)
{
//...
app.UseOAuthBearerTokens(OAuthOptions);
///Install-Package Microsoft.Owin.Cors -Version 2.1.0
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
}
我在一个链接上托管了这个WebApi项目,比如http://webaip.azurewebsites.net
我正在尝试从其他网站访问上述API的控制器方法,例如http://mysite.azurewebsites.net 有了上面的代码,我可以调用所有不安全的API方法。 (未使用Authorize属性修饰)通过javascript我无法调用/ Token进行身份验证。以下是我的javascript代码。
function LogIn() {
var loginData = {
grant_type: 'password',
username: 'username',
password: 'password',
};
$.ajax({
type: 'POST',
url: 'http://webaip.azurewebsites.net/Token/',
data: loginData
}).done(function (data) {
alert('logged in');
alert(data);
}).fail(function (data) {
alert('login problem')
}).error(function (data) {
alert('error invoking API');
});
return false;
}
我收到以下错误
XMLHttpRequest cannot load http://webaip.azurewebsites.net/Token/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysite.azurewebsites.net' is therefore not allowed access. The response had HTTP status code 404.
注意:我也尝试使用下面的代码。它也不适合我。
public static void Register(HttpConfiguration config)
{
var json = config.Formatters.JsonFormatter;
config.Formatters.Remove(config.Formatters.XmlFormatter);
//Need to have Microsoft.AspNet.WebApi.Cors package installed.
config.EnableCors(new EnableCorsAttribute("*","*","*"));
}
答案 0 :(得分:40)
经过数小时的搜索并查看了许多不同的解决方案后,我已按照以下方式设法实现了这一目标。
这种情况有很多原因。很可能你在错误的地方启用了CORS,或者启用了两次或根本没启用。
如果您正在使用Web API和Owin Token端点,那么您需要删除Web API方法中对CORS的所有引用并添加正确的owin方法,因为web api cors将无法使用Token端点,而Owin cors将工作对于Web API和令牌验证端点,让我们开始:
转到startup.cs文件并确保执行Owin 在任何其他配置运行之前的Cors。
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureAuth(app);
如果仍有问题请访问:Startup.Auth.cs并确保您的ConfigureAuth方法中包含以下内容(如果您的startup.cs文件正确,则不需要此内容)
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
答案 1 :(得分:20)
您收到该错误的原因是因为您已为webapi启用了CORS,但没有为您的/ Token端点启用此功能,这在webapi管道获取其CORS设置之前已初始化。
除了您在WebApiConfig.cs中已经完成的内容之外
您应该执行以下操作:(假设您有一个标准的WebAPI 2项目)
**打开文件:App_Start / IdenityConfig.cs **并添加以下行//允许cors为...
我在原始项目模板
中保持不变 public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
// Allows cors for the /token endpoint this is different from webapi endpoints.
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); // <-- This is the line you need
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<IdentityDb>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = true,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// rest ommited ...
return manager;
}
答案 2 :(得分:3)
请参阅我对this问题
的回答此外,如果您使用angularJS作为客户端,您可以查看我的article,其中显示了如何使用AngularJS Client中的Web API 2(个人用户帐户+启用CORS)。
希望有所帮助。
答案 3 :(得分:2)
也可以使用此解决方案:
打开providers文件夹,然后打开ApplicationOAuthProvider.cs
在GrantResourceOwnerCredentials()函数中粘贴此行:
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
答案 4 :(得分:1)
如果有人发现这个有用的
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:52436" });
await next();
});
答案 5 :(得分:0)
您不应两次使用相同的标头(我认为这是字典数据结构)
在我的情况下,我在提供程序类中有此行,因为我已经在startup.cs中启用了内核,所以不需要此行。
//context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
在我拥有并保留的startup.cs中
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
答案 6 :(得分:0)
有同样的问题。 Owin和WebAPI发生冲突,因此可以一起工作,但不能一起工作。
我在Startup.Auth.cs中的解决方案
{
var cultureQuery = context.Request.Query["culture"];
IOwinRequest req = context.Request;
IOwinResponse res = context.Response;
if (req.Path.StartsWithSegments(new PathString("/Token")))
{
// if there is an origin header
var origin = req.Headers.Get("Origin");
if (!string.IsNullOrEmpty(origin))
{
// allow the cross-site request
res.Headers.Set("Access-Control-Allow-Origin", origin);
}
// if this is pre-flight request
if (req.Method == "OPTIONS")
{
// respond immediately with allowed request methods and headers
res.StatusCode = 200;
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-
Methods", "GET", "POST");
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-
Headers", "authorization");
// no further processing
return;
}
}
...```
答案 7 :(得分:-2)
第一步是安装CORS nuget:Microsoft.AspNet.WebApi.Core
在Startup.cs中启用它
config.EnableCors();
然后你可以做任何你想做的事情:
允许控制器向外部应用程序公开,添加此属性:
[EnableCors([theHostYouWant], "*", "*")]
要允许外部身份验证,应用程序需要访问“/ Token”,允许这样做,在
中 [YourApiFolder]/Providers/ApplicationoAuthProvider.cs
找到
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
添加
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "[YourDesiredHostAddress]" });
这涵盖了控制器和“/ Token”,该属性也可以在控制器方法中添加。所以它可以解决所有问题。