401未授权发送时Ajax请求的Web API [英] 401 Unauthorized when sending ajax request to web api
问题描述
我一直在抓我的头,在这2天了。我使用的WebAPI 2.2版,我使用CORS。这种设置工作在服务器端,容许我从我的Web客户端服务器code获得授权的内容,但得到擅自在我的Ajax调用。
I've been scratching my head at this for 2 days now. I am using WebAPI version 2.2 and I am using CORS. This setup works on the server side, I am allowed to get authorized content from my web client server code but getting unauthorized in my ajax calls.
下面是我的配置:
网络API配置
WebApiConfig:
WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ApplicationCookie));
//enable cors
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filters.Add(new ValidationActionFilter());
}
}
Startup.Auth.cs:
Startup.Auth.cs:
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(UserContext<ApplicationUser>.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// 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,
CookieHttpOnly = true,
CookieName = "Outpour.Api.Auth"
}
);
//app.UseCors(CorsOptions.AllowAll);
//app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
(我试过app.UseCors(CorsOptions.AllowAll)和config.EnableCors()的每个组合)
(I've tried every combination of app.UseCors(CorsOptions.AllowAll) and config.EnableCors())
我的控制器属性:
[Authorize]
[EnableCors("http://localhost:8080", "*", "*", SupportsCredentials = true)]
[RoutePrefix("api/videos")]
public class VideosController : ApiController...
Web客户端
AJAX调用:
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
options.crossDomain = {
crossDomain: true
};
options.xhrFields = {
withCredentials: true
};
});
function ajaxGetVideoResolutionList() {
var request = {
type: "GET",
dataType: "json",
timeout: Outpour.ajaxTimeOut,
url: Outpour.apiRoot + "/videos/resolutions"
};
$.ajax(request).done(onAjaxSuccess).fail(onAjaxError);
cookie创建:
Cookie Creation:
var result = await WebApiService.Instance.AuthenticateAsync<SignInResult>(model.Email, model.Password);
FormsAuthentication.SetAuthCookie(result.AccessToken, model.RememberMe);
var claims = new[]
{
new Claim(ClaimTypes.Name, result.UserName), //Name is the default name claim type, and UserName is the one known also in Web API.
new Claim(ClaimTypes.NameIdentifier, result.UserName) //If you want to use User.Identity.GetUserId in Web API, you need a NameIdentifier claim.
};
var authTicket = new AuthenticationTicket(new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie), new AuthenticationProperties
{
ExpiresUtc = result.Expires,
IsPersistent = model.RememberMe,
IssuedUtc = result.Issued,
RedirectUri = redirectUrl
});
byte[] userData = DataSerializers.Ticket.Serialize(authTicket);
byte[] protectedData = MachineKey.Protect(userData, new[] { "Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware", DefaultAuthenticationTypes.ApplicationCookie, "v1" });
string protectedText = TextEncodings.Base64Url.Encode(protectedData);
Response.Cookies.Add(new HttpCookie("Outpour.Api.Auth")
{
HttpOnly = true,
Expires = result.Expires.UtcDateTime,
Value = protectedText
});
最后但并非最不重要的,我的头。
And last but not least, my headers.
Remote Address:127.0.0.1:8888
Request URL:http://127.0.0.1/api/videos/resolutions
Request Method:GET
Status Code:401 Unauthorized
**Request Headersview source**
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Host:127.0.0.1
Origin:http://localhost:8080
Pragma:no-cache
Proxy-Connection:keep-alive
Referer:http://localhost:8080/video/upload
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
**Response Headersview source**
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:8080
Cache-Control:no-cache
Content-Length:61
Content-Type:application/json; charset=utf-8
Date:Wed, 08 Oct 2014 04:01:19 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
WWW-Authenticate:Bearer
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
开发工具和提琴手索赔没有与请求一起发送的cookie。
Developer tools and fiddler claim there were no cookies sent with the request.
推荐答案
我相信你在这里的Cookie认证和承载标记之间的混合,你是不是送与你的要求Authorization头的访问令牌,这就是为什么你保持得到401。
以及你只需要使用 application.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)允许CORS;
键,将其删除其他地方从你的控制器甚至从配置属性。
I believe you are mixing between cookies authentication and bearer tokens here, you are not sending an access token in the Authorization header with your request, that is why you keep getting 401.
As well you need only to allow CORS using application.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
and remove it else where from your controllers attribute even from configuration.
检查我的回购这里在这里我实现了CORS和前端是AngularJS了。它工作正常。这里是href="http://ngauthenticationweb.azurewebsites.net/" rel="nofollow">现场演示的的过了这个回购协议,开放的开发工具和监控要求,你应该看到$ P $对飞行的要求之前,你看到你的HTTP GET请求。
Check my Repo here where I've implemented CORS and the front end is AngularJS too. it is working correctly. Here is the live demo too for this repo, open developer tools and monitor the requests, you should see pre-flight request before you see your HTTP get request.
如果你只需要使用承载的令牌,然后,以保护你的API,我建议你读<一href="http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/"相对=nofollow>基于令牌的认证交
If you need just to protect your API using bearer tokens then I recommend you to read Token Based Authentication post
这篇关于401未授权发送时Ajax请求的Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!