加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 401向web api发送ajax请求时未经授权

发布时间:2020-12-16 04:26:14 所属栏目:asp.Net 来源:网络整理
导读:我现在已经在这2天了.我使用的是WebAPI 2.2版,我使用的是CORS.此设置适用于服务器端,我可以从我的Web客户端服务器代码获取授权内容,但在我的ajax调用中未经授权. 这是我的配置: Web API配置 WebApiConfig: public static class WebApiConfig{ public stati
我现在已经在这2天了.我使用的是WebAPI 2.2版,我使用的是CORS.此设置适用于服务器端,我可以从我的Web客户端服务器代码获取授权内容,但在我的ajax调用中未经授权.

这是我的配置:

Web API配置

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:

// 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()的每个组合)

我的控制器属性:

[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创建:

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
            });

最后但并非最不重要的是,我的标题.

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.

解决方法

我相信你在这里混合了cookie身份验证和承载令牌,你没有在你的请求的Authorization标题中发送访问令牌,这就是你不断获得401的原因.
同样,您只需要使用application.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll)允许CORS;并从控制器属性甚至从配置中移除其他位置.

检查我的Repo here,我已经实现了CORS,前端也是AngularJS.它工作正常.对于此repo,开放式开发人员工具以及监视请求,这里也是live demo,您应该在看到HTTP get请求之前看到飞行前请求.

如果您只需要使用持有人令牌来保护您的API,那么我建议您阅读Token Based Authentication帖子

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读